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 }