diff --git a/utils/encryption_decryption/aes_cbc.go b/utils/encryption_decryption/aes_cbc.go new file mode 100644 index 00000000..9135cfb0 --- /dev/null +++ b/utils/encryption_decryption/aes_cbc.go @@ -0,0 +1,64 @@ +package encryption_decryption + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/base64" + "fmt" + "math/rand" +) + +// 必须16字节 +var key = "fusen20230405145" + +// 加密(key必须16字节),前端加解密需要先把base64转字符串再取前16字节作为iv +func CBCEncrypt(data string) (string, error) { + defer func() { + if err := recover(); err != nil { + fmt.Println("cbc decrypt err:", err) + } + }() + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return "", err + } + blockSize := len(key) + padding := blockSize - len(data)%blockSize // 填充字节 + if padding == 0 { + padding = blockSize + } + // 填充 padding 个 byte(padding) 到 data + data += string(bytes.Repeat([]byte{byte(padding)}, padding)) + ciphertext := make([]byte, aes.BlockSize+len(data)) + iv := ciphertext[:aes.BlockSize] + if _, err = rand.Read(iv); err != nil { // 将同时写到 ciphertext 的开头 + return "", err + } + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext[aes.BlockSize:], []byte(data)) + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +// 解密(key必须16字节) +func CBCDecrypt(src string) (string, error) { + defer func() { + if err := recover(); err != nil { + fmt.Println("cbc decrypt err:", err) + } + }() + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return "", err + } + ciphercode, err := base64.StdEncoding.DecodeString(src) + if err != nil { + return "", err + } + iv := ciphercode[:aes.BlockSize] // 密文的前 16 个字节为 iv + ciphercode = ciphercode[aes.BlockSize:] // 正式密文 + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(ciphercode, ciphercode) + plaintext := string(ciphercode) // ↓ 减去 padding + return plaintext[:len(plaintext)-int(plaintext[len(plaintext)-1])], nil +}