package myth import ( "bytes" "crypto/aes" "crypto/cipher" ) var ( aesKey string ) // AesCrypto define type AesCrypto struct { Key []byte } // SetAesCryptoKey set key, // key length:16, 24, 32 bytes to AES-128, AES-192, AES-256 func SetAesCryptoKey(password string) { aesKey = password } // GetAesCryptoKey get current key func GetAesCryptoKey() string { return aesKey } // NewAesCrypto new AesCrypto func NewAesCrypto() *AesCrypto { return &AesCrypto{[]byte(aesKey)} } // SetKey set key func (a *AesCrypto) SetKey(key string) { a.Key = []byte(key) } // Encrypt encrypt data func (a *AesCrypto) Encrypt(data []byte) ([]byte, error) { block, err := aes.NewCipher(a.Key) if err != nil { return nil, err } blockSize := block.BlockSize() data = pkcs5Padding(data, blockSize) blockMode := cipher.NewCBCEncrypter(block, a.Key[:blockSize]) crypted := make([]byte, len(data)) blockMode.CryptBlocks(crypted, data) return crypted, nil } // Decrypt decrypt data func (a *AesCrypto) Decrypt(crypted []byte) ([]byte, error) { block, err := aes.NewCipher(a.Key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, a.Key[:blockSize]) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = pkcs5UnPadding(origData) return origData, nil } func pkcs5Padding(cipherText []byte, blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(cipherText, padtext...) } func pkcs5UnPadding(data []byte) []byte { length := len(data) unpadding := int(data[length-1]) if unpadding >= length { return []byte(``) } return data[:(length - unpadding)] }