golang的AES加密和解密的三种模式实现(CBC/ECB/CFB)
golang的AES加密和解密的三种模式实现(CBC/ECB/CFB)
package mainimport ("bytes""crypto/aes""crypto/cipher""crypto/rand""encoding/base64""encoding/hex""io""log"
)func main() {origData := []byte("Hello World") // 待加密的数据key := []byte("ABCDEFGHIJKLMNOP") // 加密的密钥log.Println("原文:", string(origData))log.Println("------------------ CBC模式 --------------------")encrypted := AesEncryptCBC(origData, key)log.Println("密文(hex):", hex.EncodeToString(encrypted))log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))decrypted := AesDecryptCBC(encrypted, key)log.Println("解密结果:", string(decrypted))log.Println("------------------ ECB模式 --------------------")encrypted = AesEncryptECB(origData, key)log.Println("密文(hex):", hex.EncodeToString(encrypted))log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))decrypted = AesDecryptECB(encrypted, key)log.Println("解密结果:", string(decrypted))log.Println("------------------ CFB模式 --------------------")encrypted = AesEncryptCFB(origData, key)log.Println("密文(hex):", hex.EncodeToString(encrypted))log.Println("密文(base64):", base64.StdEncoding.EncodeToString(encrypted))decrypted = AesDecryptCFB(encrypted, key)log.Println("解密结果:", string(decrypted))
}// =================== CBC ======================
func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) {// 分组秘钥// NewCipher该函数限制了输入k的长度必须为16, 24或者32block, _ := aes.NewCipher(key)blockSize := block.BlockSize() // 获取秘钥块的长度origData = pkcs5Padding(origData, blockSize) // 补全码blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式encrypted = make([]byte, len(origData)) // 创建数组blockMode.CryptBlocks(encrypted, origData) // 加密return encrypted
}
func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) {block, _ := aes.NewCipher(key) // 分组秘钥blockSize := block.BlockSize() // 获取秘钥块的长度blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式decrypted = make([]byte, len(encrypted)) // 创建数组blockMode.CryptBlocks(decrypted, encrypted) // 解密decrypted = pkcs5UnPadding(decrypted) // 去除补全码return decrypted
}
func pkcs5Padding(ciphertext []byte, blockSize int) []byte {padding := blockSize - len(ciphertext)%blockSizepadtext := bytes.Repeat([]byte{byte(padding)}, padding)return append(ciphertext, padtext...)
}
func pkcs5UnPadding(origData []byte) []byte {length := len(origData)unpadding := int(origData[length-1])return origData[:(length - unpadding)]
}// =================== ECB ======================
func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {cipher, _ := aes.NewCipher(generateKey(key))length := (len(origData) + aes.BlockSize) / aes.BlockSizeplain := make([]byte, length*aes.BlockSize)copy(plain, origData)pad := byte(len(plain) - len(origData))for i := len(origData); i < len(plain); i++ {plain[i] = pad}encrypted = make([]byte, len(plain))// 分组分块加密for bs, be := 0, cipher.BlockSize(); bs <= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {cipher.Encrypt(encrypted[bs:be], plain[bs:be])}return encrypted
}
func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) {cipher, _ := aes.NewCipher(generateKey(key))decrypted = make([]byte, len(encrypted))//for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])}trim := 0if len(decrypted) > 0 {trim = len(decrypted) - int(decrypted[len(decrypted)-1])}return decrypted[:trim]
}
func generateKey(key []byte) (genKey []byte) {genKey = make([]byte, 16)copy(genKey, key)for i := 16; i < len(key); {for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {genKey[j] ^= key[i]}}return genKey
}// =================== CFB ======================
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {block, err := aes.NewCipher(key)if err != nil {panic(err)}encrypted = make([]byte, aes.BlockSize+len(origData))iv := encrypted[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {panic(err)}stream := cipher.NewCFBEncrypter(block, iv)stream.XORKeyStream(encrypted[aes.BlockSize:], origData)return encrypted
}
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {block, _ := aes.NewCipher(key)if len(encrypted) < aes.BlockSize {panic("ciphertext too short")}iv := encrypted[:aes.BlockSize]encrypted = encrypted[aes.BlockSize:]stream := cipher.NewCFBDecrypter(block, iv)stream.XORKeyStream(encrypted, encrypted)return encrypted
}
输出结果:

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
