增加对DES算法的封装

This commit is contained in:
wenzi1
2018-05-22 20:43:42 +08:00
parent 1e0cfd6d1a
commit 6fd63f69c8
2 changed files with 473 additions and 0 deletions

289
g/encoding/gdes/gdes.go Normal file
View File

@ -0,0 +1,289 @@
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gdes
import (
"crypto/des"
"crypto/cipher"
"errors"
"bytes"
)
const (
NOPADDING = iota
PKCS5PADDING
)
//ECB模式DES加密
func DesECBEncrypt(key []byte, clearText []byte, padding int) ([]byte, error) {
text, err := Padding(clearText, padding)
if err != nil {
return nil, err
}
cipherText := make([]byte, len(text))
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
for i, count := 0, len(text)/blockSize; i < count; i++ {
begin, end := i * blockSize, i * blockSize + blockSize
block.Encrypt(cipherText[begin:end], text[begin:end])
}
return cipherText, nil
}
//ECB模式DES解密
func DesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) {
text := make([]byte, len(cipherText))
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
for i, count := 0, len(text)/blockSize; i < count; i++{
begin, end := i * blockSize, i * blockSize + blockSize
block.Decrypt(text[begin:end], cipherText[begin:end])
}
clearText, err := UnPadding(text, padding)
if err != nil {
return nil, err
}
return clearText, nil
}
//ECB模式3DES加密密钥长度可以是16或24位长
func TripleDesECBEncrypt(key []byte, clearText []byte, padding int) ( []byte, error) {
if len(key) != 16 && len(key) != 24 {
return nil, errors.New("key length error")
}
text, err := Padding(clearText, padding)
if err != nil {
return nil, err
}
newKey := make([]byte, 0)
if len(key) == 16 {
newKey = append([]byte{}, key...)
newKey = append(newKey, key[:8]...)
} else {
newKey = append([]byte{}, key...)
}
block, err := des.NewTripleDESCipher(newKey)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
cipherText := make([]byte, len(text))
for i, count := 0, len(text) / blockSize; i < count; i++{
begin, end := i * blockSize, i * blockSize + blockSize
block.Encrypt(cipherText[begin:end], text[begin:end])
}
return cipherText, nil
}
//ECB模式3DES解密密钥长度可以是16或24位长
func TripleDesECBDecrypt(key []byte, cipherText []byte, padding int) ([]byte, error) {
if len(key) != 16 && len(key) != 24 {
return nil, errors.New("key length error")
}
newKey := make([]byte, 0)
if len(key) == 16 {
newKey = append([]byte{}, key...)
newKey = append(newKey, key[:8]...)
} else {
newKey = append([]byte{}, key...)
}
block, err := des.NewTripleDESCipher(newKey)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
text := make([]byte, len(cipherText))
for i, count := 0, len(text) / blockSize; i < count; i++ {
begin, end := i * blockSize, i * blockSize + blockSize
block.Decrypt(text[begin:end], cipherText[begin:end])
}
clearText, err := UnPadding(text, padding)
if err != nil {
return nil, err
}
return clearText, nil
}
//CBC模式DES加密
func DesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
if len(iv) != block.BlockSize() {
return nil, errors.New("iv length invalid")
}
text, err := Padding(clearText, padding)
if err != nil {
return nil, err
}
cipherText := make([]byte, len(text))
encrypter := cipher.NewCBCEncrypter(block, iv)
encrypter.CryptBlocks(cipherText, text)
return cipherText, nil
}
//CBC模式DES解密
func DesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
if len(iv) != block.BlockSize() {
return nil, errors.New("iv length invalid")
}
text := make([]byte, len(cipherText))
decrypter := cipher.NewCBCDecrypter(block, iv)
decrypter.CryptBlocks(text, cipherText)
clearText, err := UnPadding(text, padding)
if err != nil {
return nil, err
}
return clearText, nil
}
//CBC模式3DES加密
func TripleDesCBCEncrypt(key []byte, clearText []byte, iv []byte, padding int) ([]byte, error) {
if len(key) != 16 && len(key) != 24 {
return nil, errors.New("key length invalid")
}
newKey := make([]byte, 0)
if len(key) == 16 {
newKey = append([]byte{}, key...)
newKey = append(newKey, key[:8]...)
} else {
newKey = append([]byte{}, key...)
}
block, err := des.NewTripleDESCipher(newKey)
if err != nil {
return nil, err
}
if len(iv) != block.BlockSize() {
return nil, errors.New("iv length invalid")
}
text, err := Padding(clearText, padding)
if err != nil {
return nil, err
}
cipherText := make([]byte, len(text))
encrypter := cipher.NewCBCEncrypter(block, iv)
encrypter.CryptBlocks(cipherText, text)
return cipherText, nil
}
//CBC模式3DES解密
func TripleDesCBCDecrypt(key []byte, cipherText []byte, iv []byte, padding int) ( []byte, error) {
if len(key) != 16 && len(key) != 24 {
return nil, errors.New("key length invalid")
}
newKey := make([]byte, 0)
if len(key) == 16 {
newKey = append([]byte{}, key...)
newKey = append(newKey, key[:8]...)
} else {
newKey = append([]byte{}, key...)
}
block, err := des.NewTripleDESCipher(newKey)
if err != nil {
return nil, err
}
if len(iv) != block.BlockSize() {
return nil, errors.New("iv length invalid")
}
text := make([]byte, len(cipherText))
decrypter := cipher.NewCBCDecrypter(block, iv)
decrypter.CryptBlocks(text, cipherText)
clearText, err := UnPadding(text, padding)
if err != nil {
return nil, err
}
return clearText, nil
}
//PKCS5补位
func PKCS5Padding(text []byte, blockSize int) []byte {
padding := blockSize - len(text) % blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(text, padtext...)
}
//去除PKCS5补位
func PKCS5Unpadding(text []byte) []byte{
length := len(text)
padtext := int(text[length - 1])
return text[:(length - padtext)]
}
//补位方法
func Padding(text []byte, padding int)([]byte, error) {
switch padding {
case NOPADDING:
if len(text) % 8 != 0 {
return nil, errors.New("text length invalid")
}
case PKCS5PADDING:
return PKCS5Padding(text, 8), nil
default:
return nil, errors.New("padding type error")
}
return text, nil
}
//去除补位方法
func UnPadding(text []byte, padding int)([]byte, error) {
switch padding {
case NOPADDING:
if len(text) % 8 != 0 {
return nil, errors.New("text length invalid")
}
case PKCS5PADDING:
return PKCS5Unpadding(text), nil
default:
return nil, errors.New("padding type error.")
}
return text, nil
}

View File

@ -0,0 +1,184 @@
package gdes
import (
"testing"
"bytes"
"encoding/hex"
"fmt"
)
func TestDesECB(t *testing.T){
{
key := []byte("11111111")
text := []byte("12345678")
padding := NOPADDING
cipherText, err := DesECBEncrypt(key, text, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := DesECBDecrypt(key, cipherText, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
{
key := []byte("11111111")
text := []byte("12345678")
padding := PKCS5PADDING
cipherText, err := DesECBEncrypt(key, text, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := DesECBDecrypt(key, cipherText, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
}
func Test3DesECB(t *testing.T){
{
key := []byte("1111111111111234")
text := []byte("1234567812345678")
padding := NOPADDING
cipherText, err := TripleDesECBEncrypt(key, text, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := TripleDesECBDecrypt(key, cipherText, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
{
key := []byte("111111111111123412345678")
text := []byte("123456789")
padding := PKCS5PADDING
cipherText, err := TripleDesECBEncrypt(key, text, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := TripleDesECBDecrypt(key, cipherText, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
}
func TestDesCBC(t *testing.T){
{
key := []byte("11111111")
text := []byte("1234567812345678")
padding := NOPADDING
iv := []byte("12345678")
cipherText, err := DesCBCEncrypt(key, text, iv,padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := DesCBCDecrypt(key, cipherText, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
{
key := []byte("11111111")
text := []byte("12345678")
padding := PKCS5PADDING
iv := []byte("12345678")
cipherText, err := DesCBCEncrypt(key, text, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := DesCBCDecrypt(key, cipherText, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
}
func Test3DesCBC(t *testing.T){
{
key := []byte("1111111112345678")
text := []byte("1234567812345678")
padding := NOPADDING
iv := []byte("12345678")
cipherText, err := TripleDesCBCEncrypt(key, text, iv,padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := TripleDesCBCDecrypt(key, cipherText, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
{
key := []byte("111111111234567812345678")
text := []byte("12345678")
padding := PKCS5PADDING
iv := []byte("12345678")
cipherText, err := TripleDesCBCEncrypt(key, text, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
clearText, err := TripleDesCBCDecrypt(key, cipherText, iv, padding)
if err != nil {
t.Errorf("%v", err)
}
if bytes.Equal(clearText, text) == false {
t.Errorf("text:%v, clearText:%v", hex.EncodeToString(text), hex.EncodeToString(clearText))
}
fmt.Println("key:", hex.EncodeToString(key),"clearText:", hex.EncodeToString(clearText), "cipherText:", hex.EncodeToString(cipherText))
}
}