欢迎光临散文网 会员登陆 & 注册

go 语言实现AES大量文本加密解密

2023-07-29 00:01 作者:极极及  | 我要投稿

原文地址: https://nages.cc/archives/1690558621083

因为AES加密算法一次只能加密16个字符, 所以超过16个就需要分批次加密, 以下是本人实现的分批次加密

密钥对齐

将密钥的长度对齐至16, 24, 32位

// fix AES Key
func checkKeyAES(key string) (cipher.Block, error) {
keyLen := len(key)
if keyLen <= 32 {
 if keyLen <= 16 {
  for i := 0; i < 16-keyLen; i++ {
   key += "0"
  }
 } else if keyLen <= 24 {
  for i := 0; i < 24-keyLen; i++ {
   key += "0"
  }
 } else if keyLen <= 32 {
  for i := 0; i < 32-keyLen; i++ {
   key += "0"
  }
 }
} else {
 return nil, errors.New("key len is max 32 size")
}
return aes.NewCipher([]byte(key))
}

加密

实现大量文本的加密, 少量也可使用

// EncryptAES AES 加密字符串, key最长32位. 不足位数补充0
func EncryptAES(key string, plaintext string) (string, error) {
c, err := checkKeyAES(key)
if err != nil {
 return "", err
}
plaintextBytes := []byte(plaintext)
plaintextLen := len(plaintextBytes)
if plaintextLen <= 16 {
 out := make([]byte, 16)
 c.Encrypt(out, plaintextBytes)
 return hex.EncodeToString(out), nil
} else {
 // aes一次只能加密16字节, 超过16字节只能分批加密
 fetch := plaintextLen/16 + 1
 rs := ""
 for fetch > 0 {
  if fetch == 1 {
   out := make([]byte, 16)
   out2 := make([]byte, 16-plaintextLen)
   plaintextBytes = append(plaintextBytes, out2...)
   c.Encrypt(out, plaintextBytes)
   rs += hex.EncodeToString(out)
  } else {
   out := make([]byte, 16)
   c.Encrypt(out, plaintextBytes[:16])
   rs += hex.EncodeToString(out)
   plaintextBytes = plaintextBytes[16:]
  }
  plaintextLen -= 16
  fetch -= 1
 }
 return rs, nil
}
}

解密

实现大量文本的解密, 少量也可使用

// DecryptAES 解密文本
func DecryptAES(key string, encryptText string) (string, error) {
cipher1, err := checkKeyAES(key)
if err != nil {
 return "", err
}
decodeText, _ := hex.DecodeString(encryptText)
encryptTextLen := len(decodeText)

if encryptTextLen <= 16 {
 out := make([]byte, encryptTextLen)
 cipher1.Decrypt(out, decodeText)
 return string(out[:]), nil
} else {
 fetch := encryptTextLen / 16
 rs := make([]byte, 0)
 for fetch > 0 {
  if fetch == 1 {
   out := make([]byte, 16)
   decodeText = append(decodeText, make([]byte, 16-encryptTextLen)...)
   cipher1.Decrypt(out, decodeText)
   rs = append(rs, out...)
  } else {
   out := make([]byte, 16)
   cipher1.Decrypt(out, decodeText[:16])
   rs = append(rs, out...)
   decodeText = decodeText[16:]
  }
  encryptTextLen -= 16
  fetch -= 1
 }
 return string(rs), err
}
}

总体实现

package utils

import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"errors"
)

// EncryptAES AES 加密字符串, key最长32位. 不足位数补充0
func EncryptAES(key string, plaintext string) (string, error) {
c, err := checkKeyAES(key)
if err != nil {
 return "", err
}
plaintextBytes := []byte(plaintext)
plaintextLen := len(plaintextBytes)
if plaintextLen <= 16 {
 out := make([]byte, 16)
 c.Encrypt(out, plaintextBytes)
 return hex.EncodeToString(out), nil
} else {
 // aes一次只能加密16字节, 超过16字节只能分批加密
 fetch := plaintextLen/16 + 1
 rs := ""
 for fetch > 0 {
  if fetch == 1 {
   out := make([]byte, 16)
   out2 := make([]byte, 16-plaintextLen)
   plaintextBytes = append(plaintextBytes, out2...)
   c.Encrypt(out, plaintextBytes)
   rs += hex.EncodeToString(out)
  } else {
   out := make([]byte, 16)
   c.Encrypt(out, plaintextBytes[:16])
   rs += hex.EncodeToString(out)
   plaintextBytes = plaintextBytes[16:]
  }
  plaintextLen -= 16
  fetch -= 1
 }
 return rs, nil
}
}

// DecryptAES 解密文本
func DecryptAES(key string, encryptText string) (string, error) {
cipher1, err := checkKeyAES(key)
if err != nil {
 return "", err
}
decodeText, _ := hex.DecodeString(encryptText)
encryptTextLen := len(decodeText)

if encryptTextLen <= 16 {
 out := make([]byte, encryptTextLen)
 cipher1.Decrypt(out, decodeText)
 return string(out[:]), nil
} else {
 fetch := encryptTextLen / 16
 rs := make([]byte, 0)
 for fetch > 0 {
  if fetch == 1 {
   out := make([]byte, 16)
   decodeText = append(decodeText, make([]byte, 16-encryptTextLen)...)
   cipher1.Decrypt(out, decodeText)
   rs = append(rs, out...)
  } else {
   out := make([]byte, 16)
   cipher1.Decrypt(out, decodeText[:16])
   rs = append(rs, out...)
   decodeText = decodeText[16:]
  }
  encryptTextLen -= 16
  fetch -= 1
 }
 return string(rs), err
}
}

// fix AES Key
func checkKeyAES(key string) (cipher.Block, error) {
keyLen := len(key)
if keyLen <= 32 {
 if keyLen <= 16 {
  for i := 0; i < 16-keyLen; i++ {
   key += "0"
  }
 } else if keyLen <= 24 {
  for i := 0; i < 24-keyLen; i++ {
   key += "0"
  }
 } else if keyLen <= 32 {
  for i := 0; i < 32-keyLen; i++ {
   key += "0"
  }
 }
} else {
 return nil, errors.New("key len is max 32 size")
}
return aes.NewCipher([]byte(key))
}

测试

package main

import (
"fmt"
"go_utils/utils"
)

func 测试加密() {
key := "1111111111111111111111"
value := "This is a secret:123456, 这是一段中文文本"

fmt.Println("key", key)
fmt.Println("value", value)
fmt.Println("=======================================================")

//value = base64.StdEncoding.EncodeToString([]byte(value))
fmt.Println(value)

aes, err := utils.EncryptAES(key, value)
if err != nil {
 panic(err)
}
fmt.Println(aes)

encryptAES, err := utils.DecryptAES(key, aes)
if err != nil {
 panic(err)
}
fmt.Println(encryptAES)
}

func main() {
测试加密()
}

测试截图



go 语言实现AES大量文本加密解密的评论 (共 条)

分享到微博请遵守国家法律