AES加密属于对称加密(当然还有非对称加密rsa),对称加密个别分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。
然而golang的官网库中没有ECB的模式,至于为什么没有ECB模式,能够查看官网issue,意思就是不平安,然而咱们的确要应用的话,怎么去实现呢,上面进入正题。
我先把ECB模式实现代码贴出来,有想看剖析怎么实现的能够看上面的剖析实现过程。
type ecb struct { b cipher.Block blockSize int}func newECB(b cipher.Block) *ecb { return &ecb{ b: b, blockSize: b.BlockSize(), }}type ecbEncrypter ecbfunc NewECBEncrypter(b cipher.Block) cipher.BlockMode { return (*ecbEncrypter)(newECB(b))}func (x *ecbEncrypter) BlockSize() int { return x.blockSize }func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Encrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] }}type ecbDecrypter ecbfunc NewECBDecrypter(b cipher.Block) cipher.BlockMode { return (*ecbDecrypter)(newECB(b))}func (x *ecbDecrypter) BlockSize() int { return x.blockSize }func (x *ecbDecrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Decrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] }}
应用实例
//创立加密实例 block, err := aes.NewCipher(d.key) if err != nil { return "", err } //判断加密快的大小 blockSize := block.BlockSize() //填充 encryptBytes := pkcs7Padding(data, blockSize) //初始化加密数据接管切片 crypted := make([]byte, len(encryptBytes)) //应用cbc加密模式 //blockMode := cipher.NewCBCEncrypter(block, d.key[:blockSize]) // 应用ecb加密模式 blockMode := NewECBEncrypter(block) //执行加密 blockMode.CryptBlocks(crypted, encryptBytes)
ECB的实现,能够参照规范库中cbc的实现形式
首先咱们看CBC的代码实现
NewCBCEncrypter函数返回了一个BlockMode接口,阐明cbcEncrypter是实现了BlockMode接口
type cbc struct { b Block blockSize int iv []byte tmp []byte}func newCBC(b Block, iv []byte) *cbc { return &cbc{ b: b, blockSize: b.BlockSize(), iv: dup(iv), tmp: make([]byte, b.BlockSize()), }}type cbcEncrypter cbc// NewCBCEncrypter函数返回了一个BlockMode接口,阐明cbcEncrypter是实现了BlockMode接口func NewCBCEncrypter(b Block, iv []byte) BlockMode { ... return (*cbcEncrypter)(newCBC(b, iv))}type BlockMode interface { BlockSize() int CryptBlocks(dst, src []byte)}
咱们也能够仿照cbc,用ecb也去实现BlockMode接口
type ecb struct { b cipher.Block blockSize int}func newECB(b cipher.Block) *ecb { return &ecb{ b: b, blockSize: b.BlockSize(), }}type ecbEncrypter ecbfunc NewECBEncrypter(b cipher.Block) cipher.BlockMode { return (*ecbEncrypter)(newECB(b))}func (x *ecbEncrypter) BlockSize() int { return x.blockSize }// 具体这块的算法,就不多讲了,有趣味理解的敌人,能够去看看cbc和ecb的算法区别func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { if len(src)%x.blockSize != 0 { panic("crypto/cipher: input not full blocks") } if len(dst) < len(src) { panic("crypto/cipher: output smaller than input") } for len(src) > 0 { x.b.Encrypt(dst, src[:x.blockSize]) src = src[x.blockSize:] dst = dst[x.blockSize:] }}
ecbEncrypter也实现了BlockMode的接口,就能够依照cbc的形式进行解密了
//应用cbc加密模式 blockMode := cipher.NewCBCEncrypter(block, d.key[:blockSize]) // 应用ecb加密模式 blockMode := NewECBEncrypter(block)