最近有一个需求需要在golang中实现AES ECB模式的加密和解密,看了一下官方文档和相关资料发现golang 官方包并没有完善的实现,于是自己尝试写了一个,本文中的AES算法是基于ECB模式,关于AES算法的几种模式原理大家可以去百度搜索一下,集中模式如下。
1.电码本模式(ElectronicCodebookBook(ECB))
2.密码分组链接模式(CipherBlockChaining(CBC))
3.计算器模式(Counter(CTR))
4.密码反馈模式(CipherFeedBack(CFB))
我这里采用的ECB加密基本原理是将明文切分成若干相同的小段,然后对每一段进行加密和解密,最后组合就是最终的结果,AES算法有AES-128、AES-192、AES-256三种,分别对应的key是 16、24、32字节长度,同样对应的加密解密区块长度BlockSize也是16、24、32字节长度。
下面贴上我的实现代码:
- package main
- import (
- "bytes"
- "crypto/aes"
- "fmt"
- )
- //AES ECB模式的加密解密
- type AesTool struct {
- //128 192 256位的其中一个 长度 对应分别是 16 24 32字节长度
- Key []byte
- BlockSize int
- }
- func NewAesTool(key []byte,blockSize int) *AesTool {
- return &AesTool{Key: key,BlockSize: blockSize}
- }
- func (this *AesTool) padding(src []byte) []byte {
- //填充个数
- paddingCount := aes.BlockSize - len(src)%aes.BlockSize
- if paddingCount == 0 {
- return src
- } else {
- //填充数据
- return append(src,bytes.Repeat([]byte{byte(0)},paddingCount)...)
- }
- }
- //unpadding
- func (this *AesTool) unPadding(src []byte) []byte {
- for i := len(src) - 1; ; i-- {
- if src[i] != 0 {
- return src[:i+1]
- }
- }
- return nil
- }
- func (this *AesTool) Encrypt(src []byte) ([]byte,error) {
- //key只能是 16 24 32长度
- block,err := aes.NewCipher([]byte(this.Key))
- if err != nil {
- return nil,err
- }
- //padding
- src = this.padding(src)
- //返回加密结果
- encryptData := make([]byte,len(src))
- //存储每次加密的数据
- tmpData := make([]byte,this.BlockSize)
- //分组分块加密
- for index := 0; index < len(src); index += this.BlockSize {
- block.Encrypt(tmpData,src[index:index+this.BlockSize])
- copy(encryptData,tmpData)
- }
- return encryptData,nil
- }
- func (this *AesTool) Decrypt(src []byte) ([]byte,err
- }
- //返回加密结果
- decryptData := make([]byte,this.BlockSize)
- //分组分块加密
- for index := 0; index < len(src); index += this.BlockSize {
- block.Decrypt(tmpData,src[index:index+this.BlockSize])
- copy(decryptData,tmpData)
- }
- return this.unPadding(decryptData),nil
- }
- //测试padding unpadding
- func TestPadding() {
- tool := NewAesTool([]byte{},16)
- src := []byte{1,2,3,4,5}
- src = tool.padding(src)
- fmt.Println(src)
- src = tool.unPadding(src)
- fmt.Println(src)
- }
- //测试AES ECB 加密解密
- func TestEncryptDecrypt() {
- key := []byte{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}
- blickSize := 16
- tool := NewAesTool(key,blickSize)
- encryptData,_ := tool.Encrypt([]byte("32334erew32"))
- fmt.Println(encryptData)
- decryptData,_ := tool.Decrypt(encryptData)
- fmt.Println(string(decryptData))
- }
- func main() {
- fmt.Println("Padding Test........")
- TestPadding()
- fmt.Println("AES ECB加密解密测试........")
- TestEncryptDecrypt()
- }