6 changed files with 156 additions and 9 deletions
@ -0,0 +1,90 @@ |
|||||||
|
package security |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"crypto/aes" |
||||||
|
"crypto/cipher" |
||||||
|
"crypto/rand" |
||||||
|
"encoding/base64" |
||||||
|
) |
||||||
|
|
||||||
|
func GenAesKey256() string { |
||||||
|
key := genAesKey(256) |
||||||
|
return base64.StdEncoding.EncodeToString(key) |
||||||
|
} |
||||||
|
|
||||||
|
func genAesKey(keySize int) []byte { |
||||||
|
var key = make([]byte, keySize/8) |
||||||
|
_, err := rand.Read(key) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
return key |
||||||
|
} |
||||||
|
|
||||||
|
// EncryptAesCBC
|
||||||
|
// src -> 要加密的原文
|
||||||
|
// key -> 秘钥, 和加密秘钥相同, 大小为: 8byte
|
||||||
|
func EncryptAesCBC(src, key []byte) ([]byte, error) { |
||||||
|
block, err := aes.NewCipher(key) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
blockSize := block.BlockSize() |
||||||
|
// 对最后一个明文分组进行数据填充
|
||||||
|
src = pkcs5Padding(src, blockSize) |
||||||
|
// 3.创建一个密码分组为链接模式的,底层使用 DES 加密的 BlockMode 接口
|
||||||
|
// 参数 iv 的长度,必须等于 b 的块尺寸
|
||||||
|
iv := make([]byte, blockSize) |
||||||
|
copy(iv, key) |
||||||
|
blackMode := cipher.NewCBCEncrypter(block, iv) |
||||||
|
// 5.加密连续的数据块
|
||||||
|
dst := make([]byte, len(src)) |
||||||
|
blackMode.CryptBlocks(dst, src) |
||||||
|
return dst, nil |
||||||
|
} |
||||||
|
|
||||||
|
// DecryptAesCBC
|
||||||
|
// src -> 要解密的密文
|
||||||
|
// key -> 秘钥, 和加密秘钥相同, 大小为: 8byte
|
||||||
|
func DecryptAesCBC(src, key []byte) ([]byte, error) { |
||||||
|
// 1. 创建并返回一个使用DES算法的cipher.Block接口
|
||||||
|
block, err := aes.NewCipher(key) |
||||||
|
// 2. 判断是否创建成功
|
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
blockSize := block.BlockSize() |
||||||
|
// 3. 创建一个密码分组为链接模式的, 底层使用DES解密的BlockMode接口
|
||||||
|
iv := make([]byte, blockSize) |
||||||
|
copy(iv, key) |
||||||
|
blockMode := cipher.NewCBCDecrypter(block, iv) |
||||||
|
// 4. 解密数据
|
||||||
|
dst := src |
||||||
|
blockMode.CryptBlocks(src, dst) |
||||||
|
// 5. 去掉最后一组填充的数据
|
||||||
|
dst = pkcs5UnPadding(dst) |
||||||
|
// 6. 返回结果
|
||||||
|
return dst, nil |
||||||
|
} |
||||||
|
|
||||||
|
// PKCS5Padding 使用pks5的方式填充
|
||||||
|
func pkcs5Padding(ciphertext []byte, blockSize int) []byte { |
||||||
|
// 1. 计算最后一个分组缺多少个字节
|
||||||
|
padding := blockSize - (len(ciphertext) % blockSize) |
||||||
|
// 2. 创建一个大小为padding的切片, 每个字节的值为padding
|
||||||
|
padText := bytes.Repeat([]byte{byte(padding)}, padding) |
||||||
|
// 3. 将padText添加到原始数据的后边, 将最后一个分组缺少的字节数补齐
|
||||||
|
newText := append(ciphertext, padText...) |
||||||
|
return newText |
||||||
|
} |
||||||
|
|
||||||
|
// PKCS5UnPadding 删除pks5填充的尾部数据
|
||||||
|
func pkcs5UnPadding(origData []byte) []byte { |
||||||
|
// 1. 计算数据的总长度
|
||||||
|
length := len(origData) |
||||||
|
// 2. 根据填充的字节值得到填充的次数
|
||||||
|
number := int(origData[length-1]) |
||||||
|
// 3. 将尾部填充的number个字节去掉
|
||||||
|
return origData[:(length - number)] |
||||||
|
} |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
package security |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/base64" |
||||||
|
"fmt" |
||||||
|
"reflect" |
||||||
|
"testing" |
||||||
|
) |
||||||
|
|
||||||
|
func TestGenAesKey256(t *testing.T) { |
||||||
|
for range 10 { |
||||||
|
key := GenAesKey256() |
||||||
|
fmt.Println(key) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 参考:https://www.yisu.com/zixun/696240.html
|
||||||
|
func TestAes(t *testing.T) { |
||||||
|
defer func() { |
||||||
|
if r := recover(); r != nil { |
||||||
|
fmt.Println("recover...", r.(error).Error(), reflect.TypeOf(r)) |
||||||
|
} |
||||||
|
}() |
||||||
|
|
||||||
|
// aesKeyStr := GetAesKey256()
|
||||||
|
aesKeyStr := "VzKw8Vx+K8k1nO9fmPjhv8o+8l4vqpF+fjsbvXf0j4o=" |
||||||
|
|
||||||
|
fmt.Println(aesKeyStr) |
||||||
|
key, _ := base64.StdEncoding.DecodeString(aesKeyStr) |
||||||
|
|
||||||
|
text := []byte("hello sig.pub") |
||||||
|
encrypt, _ := EncryptAesCBC(text, key) |
||||||
|
fmt.Println(base64.URLEncoding.EncodeToString(text)) |
||||||
|
|
||||||
|
result, err := DecryptAesCBC(encrypt, key) |
||||||
|
if err != nil { |
||||||
|
t.Errorf("decrypt aes cbc failed: %v", err) |
||||||
|
return |
||||||
|
} |
||||||
|
fmt.Println("result:", string(result)) |
||||||
|
} |
||||||
Loading…
Reference in new issue