PaymentCenter/app/utils/encrypt/aes/aes.go

102 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package aes
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
"math/big"
)
const (
TestKey = "ROK0nAaxcsI0KRCy8VJgLlnlfjWYAOHk"
)
// 加密函数
func Encrypt(plaintext, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 加密后的数据会比原文长,因为需要添加一些填充字节
// PKCS#7填充
plaintext = pkcs7Padding(plaintext, block.BlockSize())
// 创建一个cipher.BlockMode这里使用CBC模式
// 需要一个iv初始化向量它的长度和Block的块大小相同
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
// 返回的密文包括iv和加密后的数据
return ciphertext, nil
}
// 解密函数
func Decrypt(ciphertext, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(ciphertext) < aes.BlockSize {
return nil, fmt.Errorf("ciphertext too short")
}
// 提取iv
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// 创建一个cipher.BlockMode
mode := cipher.NewCBCDecrypter(block, iv)
// 解密
mode.CryptBlocks(ciphertext, ciphertext)
// 去除PKCS#7填充
plaintext, err := pkcs7Unpadding(ciphertext, block.BlockSize())
if err != nil {
return nil, err
}
return plaintext, nil
}
// PKCS#7填充
func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// 去除PKCS#7填充
func pkcs7Unpadding(ciphertext []byte, blockSize int) ([]byte, error) {
length := len(ciphertext)
unpadding := int(ciphertext[length-1])
if unpadding > blockSize || unpadding == 0 {
return nil, fmt.Errorf("invalid padding")
}
return ciphertext[:(length - unpadding)], nil
}
func GenerateRandomStringCrypto(length int) (string, error) {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var bytes = make([]byte, length)
for i := range bytes {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
if err != nil {
return "", err
}
bytes[i] = charset[num.Int64()]
}
return string(bytes), nil
}