golang实现AES ECB模式的加密和解密

最近有一个需求需要在golang中实现AES ECB模式的加密和解密, 看了一下官方文档和相关资料发现golang 官方包并没有完善的实现,于是自己尝试写了一个,本文中的AES算法是基于ECB模式,关于AES算法的几种模式原理大家可以去百度搜索一下,集中模式如下。

  1. 电码本模式(Electronic Codebook Book (ECB))
  2. 密码分组链接模式(Cipher Block Chaining (CBC))
  3. 计算器模式(Counter (CTR))
  4. 密码反馈模式(Cipher FeedBack (CFB))
  5. 输出反馈模式(Output FeedBack (OFB))

我这里采用的ECB加密基本原理是将明文切分成若干相同的小段,然后对每一段进行加密和解密,最后组合就是最终的结果,AES算法有AES-128、AES-192、AES-256三种,分别对应的key是 16、24、32字节长度,同样对应的加密解密区块长度BlockSize也是16、24、32字节长度。

下面贴上我的实现代码:

  1. package main
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "fmt"
  6. )
  7. //AES ECB模式的加密解密
  8. type AesTool struct {
  9. //128 192 256位的其中一个 长度 对应分别是 16 24 32字节长度
  10. Key []byte
  11. BlockSize int
  12. }
  13. func NewAesTool(key []byte, blockSize int) *AesTool {
  14. return &AesTool{Key: key, BlockSize: blockSize}
  15. }
  16. func (this *AesTool) padding(src []byte) []byte {
  17. //填充个数
  18. paddingCount := aes.BlockSize - len(src)%aes.BlockSize
  19. if paddingCount == 0 {
  20. return src
  21. } else {
  22. //填充数据
  23. return append(src, bytes.Repeat([]byte{byte(0)}, paddingCount)...)
  24. }
  25. }
  26. //unpadding
  27. func (this *AesTool) unPadding(src []byte) []byte {
  28. for i := len(src) - 1; ; i-- {
  29. if src[i] != 0 {
  30. return src[:i+1]
  31. }
  32. }
  33. return nil
  34. }
  35. func (this *AesTool) Encrypt(src []byte) ([]byte, error) {
  36. //key只能是 16 24 32长度
  37. block, err := aes.NewCipher([]byte(this.Key))
  38. if err != nil {
  39. return nil, err
  40. }
  41. //padding
  42. src = this.padding(src)
  43. //返回加密结果
  44. encryptData := make([]byte, len(src))
  45. //存储每次加密的数据
  46. tmpData := make([]byte, this.BlockSize)
  47. //分组分块加密
  48. for index := 0; index < len(src); index += this.BlockSize {
  49. block.Encrypt(tmpData, src[index:index+this.BlockSize])
  50. copy(encryptData, tmpData)
  51. }
  52. return encryptData, nil
  53. }
  54. func (this *AesTool) Decrypt(src []byte) ([]byte, error) {
  55. //key只能是 16 24 32长度
  56. block, err := aes.NewCipher([]byte(this.Key))
  57. if err != nil {
  58. return nil, err
  59. }
  60. //返回加密结果
  61. decryptData := make([]byte, len(src))
  62. //存储每次加密的数据
  63. tmpData := make([]byte, this.BlockSize)
  64. //分组分块加密
  65. for index := 0; index < len(src); index += this.BlockSize {
  66. block.Decrypt(tmpData, src[index:index+this.BlockSize])
  67. copy(decryptData, tmpData)
  68. }
  69. return this.unPadding(decryptData), nil
  70. }
  71. //测试padding unpadding
  72. func TestPadding() {
  73. tool := NewAesTool([]byte{}, 16)
  74. src := []byte{1, 2, 3, 4, 5}
  75. src = tool.padding(src)
  76. fmt.Println(src)
  77. src = tool.unPadding(src)
  78. fmt.Println(src)
  79. }
  80. //测试AES ECB 加密解密
  81. func TestEncryptDecrypt() {
  82. key := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}
  83. blickSize := 16
  84. tool := NewAesTool(key, blickSize)
  85. encryptData, _ := tool.Encrypt([]byte("32334erew32"))
  86. fmt.Println(encryptData)
  87. decryptData, _ := tool.Decrypt(encryptData)
  88. fmt.Println(string(decryptData))
  89. }
  90. func main() {
  91. fmt.Println("Padding Test........")
  92. TestPadding()
  93. fmt.Println("AES ECB加密解密测试........")
  94. TestEncryptDecrypt()
  95. }

作者:UsherYue
来源:CSDN
原文:https://blog.csdn.net/yue7603835/article/details/73395580
版权声明:本文为博主原创文章,转载请附上博文链接!