package yapingtech import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" ) // PKCS7Padding pads the input text according to the PKCS7 standard. func PKCS7Padding(data []byte, blockSize int) []byte { padding := blockSize - len(data)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(data, padText...) } // Encrypt encrypts the given plaintext using AES-256-ECB. func Encrypt(plaintext, key string) (string, error) { // Truncate the key to 32 bytes truncatedKey := []byte(key)[:32] block, err := aes.NewCipher(truncatedKey) if err != nil { return "", err } paddedText := PKCS7Padding([]byte(plaintext), aes.BlockSize) cipherText := make([]byte, len(paddedText)) mode := NewECBEncrypter(block) mode.CryptBlocks(cipherText, paddedText) return base64.StdEncoding.EncodeToString(cipherText), nil } // ecbEncrypter is a custom implementation of ECB encryption mode. type ecbEncrypter struct { b cipher.Block blockSize int } func NewECBEncrypter(b cipher.Block) cipher.BlockMode { return &ecbEncrypter{ b: b, blockSize: b.BlockSize(), } } func (x *ecbEncrypter) BlockSize() int { return x.blockSize } func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Encrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] } }