package aesx import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "errors" "fmt" "io" ) func PKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS7UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } // AES加密,CBC func AesEncrypt(origData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() origData = PKCS7Padding(origData, blockSize) blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) crypted := make([]byte, len(origData)) blockMode.CryptBlocks(crypted, origData) return crypted, nil } // AES解密 func AesDecrypt(crypted, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) origData := make([]byte, len(crypted)) blockMode.CryptBlocks(origData, crypted) origData = PKCS7UnPadding(origData) return origData, nil } /* AES CBC 加密 key:加密key plaintext:加密明文 ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] */ func AESCBCEncrypt(key, plaintext string) (ciphertext string,err error) { plainbyte := []byte(plaintext) keybyte := []byte(key) if len(plainbyte)%aes.BlockSize != 0 { return "",errors.New ("plaintext is not a multiple of the block size") } block, err := aes.NewCipher(keybyte) if err != nil { return "",err } cipherbyte := make([]byte, aes.BlockSize+len(plainbyte)) iv := cipherbyte[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "",err } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherbyte[aes.BlockSize:], plainbyte) ciphertext = fmt.Sprintf("%x\n", cipherbyte) return } /* AES CBC 解码 key:解密key ciphertext:加密返回的串 plaintext:解密后的字符串 */ func AESCBCDecrypter(key, ciphertext string) (plaintext string,err error) { cipherbyte, _ := hex.DecodeString(ciphertext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "",err } if len(cipherbyte) < aes.BlockSize { return "", errors.New("ciphertext too short") } iv := cipherbyte[:aes.BlockSize] cipherbyte = cipherbyte[aes.BlockSize:] if len(cipherbyte)%aes.BlockSize != 0 { return "", errors.New("ciphertext is not a multiple of the block size") } mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(cipherbyte, cipherbyte) //fmt.Printf("%s\n", ciphertext) plaintext = string(cipherbyte[:]) return } /* AES GCM 加密 key:加密key plaintext:加密明文 ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] */ func AESGCMEncrypt(key, plaintext string) (ciphertext, noncetext string, err error) { plainbyte := []byte(plaintext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", "", err } // 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。 nonce := make([]byte, 12) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return "", "", err } aesgcm, err := cipher.NewGCM(block) if err != nil { return "", "", err } cipherbyte := aesgcm.Seal(nil, nonce, plainbyte, nil) ciphertext = fmt.Sprintf("%x\n", cipherbyte) noncetext = fmt.Sprintf("%x\n", nonce) return } /* AES CBC 解码 key:解密key ciphertext:加密返回的串 plaintext:解密后的字符串 */ func AESGCMDecrypter(key, ciphertext, noncetext string) (plaintext string, err error) { cipherbyte, _ := hex.DecodeString(ciphertext) nonce, _ := hex.DecodeString(noncetext) keybyte := []byte(key) block, err := aes.NewCipher(keybyte) if err != nil { return "", err } aesgcm, err := cipher.NewGCM(block) if err != nil { return "", err } plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil) if err != nil { return "", err } //fmt.Printf("%s\n", ciphertext) plaintext = string(plainbyte[:]) return }