go AES 加密 和解密

其实网上关于aes加密和解密的文章很多,尤其是 https://cloud.tencent.com/developer/section/1140748, 只是我个人喜欢用字符串形式,所以整理了一下:

package utils

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
)

/*
	AES  CBC 加密
	key:加密key
	plaintext:加密明文
	ciphertext:解密返回字节字符串[ 整型以十六进制方式显示]

*/
func AESCBCEncrypt(key, plaintext string) (ciphertext string) {
	plainbyte := []byte(plaintext)
	keybyte := []byte(key)
	if len(plainbyte)%aes.BlockSize != 0 {
		panic("plaintext is not a multiple of the block size")
	}
	block, err := aes.NewCipher(keybyte)
	if err != nil {
		panic(err)
	}

	cipherbyte := make([]byte, aes.BlockSize+len(plainbyte))
	iv := cipherbyte[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		panic(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) {
	cipherbyte, _ := hex.DecodeString(ciphertext)
	keybyte := []byte(key)
	block, err := aes.NewCipher(keybyte)
	if err != nil {
		panic(err)
	}
	if len(cipherbyte) < aes.BlockSize {
		panic("ciphertext too short")
	}

	iv := cipherbyte[:aes.BlockSize]
	cipherbyte = cipherbyte[aes.BlockSize:]
	if len(cipherbyte)%aes.BlockSize != 0 {
		panic("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) {
	plainbyte := []byte(plaintext)
	keybyte := []byte(key)
	block, err := aes.NewCipher(keybyte)
	if err != nil {
		panic(err.Error())
	}

	// 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。
	nonce := make([]byte, 12)
	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
		panic(err.Error())
	}

	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		panic(err.Error())
	}

	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) {
	cipherbyte, _ := hex.DecodeString(ciphertext)
	nonce, _ := hex.DecodeString(noncetext)
	keybyte := []byte(key)
	block, err := aes.NewCipher(keybyte)
	if err != nil {
		panic(err.Error())
	}

	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		panic(err.Error())
	}

	plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil)
	if err != nil {
		panic(err.Error())
	}

	//fmt.Printf("%s\n", ciphertext)
	plaintext = string(plainbyte[:])
	return
}

使用很简单:

key := "example key 1234"
plaintext := "exampleplaintext"
ciphertext := utils.AESCBCEncrypt(key, plaintext)
fmt.Println(ciphertext)

plaintext = utils.AESCBCDecrypter(key, ciphertext)
fmt.Println(plaintext)
///GCM
noncetext := ""
ciphertext, noncetext = utils.AESGCMEncrypt(key, plaintext)
fmt.Println(ciphertext)

plaintext = utils.AESGCMDecrypter(key, ciphertext, noncetext)
fmt.Println(plaintext)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值