共计 2787 个字符,预计需要花费 7 分钟才能阅读完成。
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 ecb
func 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 ecb
func 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 ecb
func 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)
正文完