关于go:golang-aes加密-扩展ecb模式

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)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理