From 6fd63f69c8603d3b408007885a49810ba79d5799 Mon Sep 17 00:00:00 2001 From: wenzi1 Date: Tue, 22 May 2018 20:43:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9DES=E7=AE=97?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/encoding/gdes/gdes.go | 289 +++++++++++++++++++++++++++++++++++ g/encoding/gdes/gdes_test.go | 184 ++++++++++++++++++++++ 2 files changed, 473 insertions(+) create mode 100644 g/encoding/gdes/gdes.go create mode 100644 g/encoding/gdes/gdes_test.go diff --git a/g/encoding/gdes/gdes.go b/g/encoding/gdes/gdes.go new file mode 100644 index 000000000..f0370a143 --- /dev/null +++ b/g/encoding/gdes/gdes.go @@ -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 +} \ No newline at end of file diff --git a/g/encoding/gdes/gdes_test.go b/g/encoding/gdes/gdes_test.go new file mode 100644 index 000000000..49a3d37d6 --- /dev/null +++ b/g/encoding/gdes/gdes_test.go @@ -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)) + } +} \ No newline at end of file