From 2a0eae897556239e2df4c7a14d26a9730f56344c Mon Sep 17 00:00:00 2001 From: zhangxinxiang Date: Tue, 18 Jun 2019 04:07:35 +0800 Subject: [PATCH] gaes encryption and decryption add CFB mode --- g/crypto/gaes/gaes.go | 63 ++++++++++++++++++++++++++++++++++++++ g/crypto/gaes/gaes_test.go | 22 +++++++++++++ 2 files changed, 85 insertions(+) diff --git a/g/crypto/gaes/gaes.go b/g/crypto/gaes/gaes.go index 14f34f44b..40d381f9f 100644 --- a/g/crypto/gaes/gaes.go +++ b/g/crypto/gaes/gaes.go @@ -98,3 +98,66 @@ func PKCS5UnPadding(src []byte, blockSize int) ([]byte, error) { return src[:(length - unpadding)], nil } + +/** + * AES加密, 使用CFB模式. + * 注意key必须为16/24/32位长度,padding返回补位长度,iv初始化向量为非必需参数 + * author: zseeker + * date: 2019-06-18 + */ +func EncryptCFB(plainText []byte, key []byte, padding *int, iv ...[]byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + blockSize := block.BlockSize() + plainText, *padding = ZeroPadding(plainText, blockSize) //补位0 + ivValue := ([]byte)(nil) + if len(iv) > 0 { + ivValue = iv[0] + } else { + ivValue = []byte(ivDefValue) + } + stream := cipher.NewCFBEncrypter(block, ivValue) + cipherText := make([]byte, len(plainText)) + stream.XORKeyStream(cipherText, plainText) + return cipherText, nil +} + +/** + * AES解密, 使用CFB模式. + * 注意key必须为16/24/32位长度,unpadding为去补位长度,iv初始化向量为非必需参数 + * author: zseeker + * date: 2019-06-18 + */ +func DecryptCFB(cipherText []byte, key []byte, unpadding int, iv ...[]byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(cipherText) < aes.BlockSize { + return nil, errors.New("cipherText too short") + } + ivValue := ([]byte)(nil) + if len(iv) > 0 { + ivValue = iv[0] + } else { + ivValue = []byte(ivDefValue) + } + stream := cipher.NewCFBDecrypter(block, ivValue) + plainText := make([]byte, len(cipherText)) + stream.XORKeyStream(plainText, cipherText) + plainText = ZeroUnPadding(plainText, unpadding) //去补位0 + return plainText, nil +} + +func ZeroPadding(ciphertext []byte, blockSize int) ([]byte, int) { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(0)}, padding) + return append(ciphertext, padtext...), padding +} + +func ZeroUnPadding(plaintext []byte, unpadding int) []byte { + length := len(plaintext) + return plaintext[:(length - unpadding)] +} \ No newline at end of file diff --git a/g/crypto/gaes/gaes_test.go b/g/crypto/gaes/gaes_test.go index 57f307a6e..119900065 100644 --- a/g/crypto/gaes/gaes_test.go +++ b/g/crypto/gaes/gaes_test.go @@ -32,6 +32,10 @@ var ( keys = []byte("12345678912345678912345678912346") key_err = []byte("1234") key_32_err = []byte("1234567891234567891234567891234 ") + + // cfb模式blockSize补位长度, add by zseeker + padding_size = 16 - len(content) + content_16_cfb, _ = gbase64.Decode("oSmget3aBDT1nJnBp8u6kA==") ) func TestEncrypt(t *testing.T) { @@ -125,3 +129,21 @@ func TestPKCS5UnPaddingErr(t *testing.T) { gtest.AssertNE(err, nil) }) } + +func TestEncryptCFB(t *testing.T) { + gtest.Case(t, func() { + var padding int = 0 + data, err := gaes.EncryptCFB(content, key_16, &padding, iv) + gtest.Assert(err, nil) + gtest.Assert(padding, padding_size) + gtest.Assert(data, []byte(content_16_cfb)) + }) +} + +func TestDecryptCFB(t *testing.T) { + gtest.Case(t, func() { + decrypt, err := gaes.DecryptCFB([]byte(content_16_cfb), key_16, padding_size, iv) + gtest.Assert(err, nil) + gtest.Assert(decrypt, content) + }) +}