最近有一个需求需要在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字节长度。
下面贴上我的实现代码:
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, error) { //key只能是 16 24 32长度 block, err := aes.NewCipher([]byte(this.Key)) if err != nil { return nil, err } //返回加密结果 decryptData := make([]byte, len(src)) //存储每次加密的数据 tmpData := 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() }