栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang实现AES有五种加密模式函数,Encrypt加解密字符串输出

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang实现AES有五种加密模式函数,Encrypt加解密字符串输出


package libs

import (
   "bytes"
   "crypto/aes"
   "crypto/cipher"
   "encoding/base64"
   "encoding/hex"
   "strings"
   "errors"
)

func AesEncryptCBC(orig string, key string) string {
   // 转成字节数组
   origData := []byte(orig)
   k := []byte(key)
   // 分组秘钥
   // NewCipher该函数限制了输入k的长度必须为16, 24或者32
   block, _ := aes.NewCipher(k)
   // 获取秘钥块的长度
   blockSize := block.BlockSize()
   // 补全码
   origData = PKCS7Padding(origData, blockSize)
   // 加密模式
   blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
   // 创建数组
   cryted := make([]byte, len(origData))
   // 加密
   blockMode.CryptBlocks(cryted, origData)
   return base64.StdEncoding.EncodeToString(cryted)
}
func AesDecryptCBC(cryted string, key string) string {
   // 转成字节数组
   crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
   k := []byte(key)
   // 分组秘钥
   block, _ := aes.NewCipher(k)
   // 获取秘钥块的长度
   blockSize := block.BlockSize()
   // 加密模式
   blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
   // 创建数组
   orig := make([]byte, len(crytedByte))
   // 解密
   blockMode.CryptBlocks(orig, crytedByte)
   // 去补全码
   orig = PKCS7UnPadding(orig)
   return string(orig)
}
//补码
//AES加密数据块分组长度必须为128bit(byte[16]),密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。
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)]
}



func AESEncryptECBStr(source string, keys string)  string {
   // 字符串转换成切片
   src := []byte(source)
   key := []byte(keys)
   cipher, _ := aes.NewCipher(generateKeys(key))
   length := (len(src) + aes.BlockSize) / aes.BlockSize
   plain := make([]byte, length*aes.BlockSize)
   copy(plain, src)
   pad := byte(len(plain) - len(src))
   for i := len(src); i < len(plain); i++ {
      plain[i] = pad
   }
   encrypted := make([]byte, len(plain))
   // 分组分块加密
   for bs, be := 0, cipher.BlockSize(); bs <= len(src); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
      cipher.Encrypt(encrypted[bs:be], plain[bs:be])
   }

   //return encrypted
   encryptstr :=strings.ToUpper(hex.EncodeToString(encrypted))
   return encryptstr
}

func AESDecryptECBStr(encrypteds string, keys string) string {
   // 字符串转换成切片
   //encrypted := []byte(encrypteds)
   encrypted, _ := hex.DecodeString(encrypteds)
   key := []byte(keys)

   cipher, _ := aes.NewCipher(generateKeys(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 := 0
   if len(decrypted) > 0 {
      trim = len(decrypted) - int(decrypted[len(decrypted)-1])
   }
   return  string(decrypted[:trim])
}

func generateKeys(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
}

// 为了方便,声明该函数,省去错误处理

// 测试解码
//const testStr = "R2/or63oqIDnvJbnqIs="
//str :=mustDecode(base64.StdEncoding,testStr)    // 打印:R2/or63oqIDnvJbnqIs=
//fmt.Println(str)

func Base64DecodeStr(enc *base64.Encoding, str string) string {
   data, err := enc.DecodeString(str)
   if err != nil {
      panic(err)
   }
   return string(data)
}

// 该函数测试编解码
// enc为要测试的Encoding对象,str为要测试的字符串
//const testStr = "Go语言编程"

// 测试StdEncoding,注意打印结果里的/为URL中的特殊字符,最后有一个padding,mysql的base64加密
//testEncoding(base64.StdEncoding, testStr)    // 打印:R2/or63oqIDnvJbnqIs=

 测试URLEncoding,可以看到/被替换为_
//testEncoding(base64.URLEncoding, testStr)    // 打印:R2_or63oqIDnvJbnqIs=
//
 测试RawStdEncoding,可以看到去掉了padding
//testEncoding(base64.RawStdEncoding, testStr) // 打印:R2/or63oqIDnvJbnqIs
//
 测试RawURLEncoding,可以看到/被替换Wie_,并且却掉了padding
//testEncoding(base64.RawURLEncoding, testStr) // 打印:R2_or63oqIDnvJbnqIs
func Base64EncodeStr(enc *base64.Encoding, str string) string {
   // 编码
   encStr := enc.EncodeToString([]byte(str))
   // 解码
   decStr := Base64DecodeStr(enc, encStr)
   if decStr != str {  // 编码后再解码应该与原始字符串相同
      // 这里判断如果不同,则panic
      panic(errors.New("unequal!"))
   }
   return encStr
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/944204.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号