DES--------Golang对称加密之模式问题实战

发布时间:2020-06-16 15:47:43 作者:asd1123509133
来源:网络 阅读:14968

1. 背景

近期项目在对接第三方产品,传输过程中涉及到数据加密, 数据加密流程为:

DES介绍

DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行"异或"运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

DES常见加密模式

CBC(加密分组链接模式)

密文分组链接方式,这是golang和.NET封装的DES算法的默认模式,它比较麻烦,加密步骤如下:

  1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,就涉及到数据补位了)
  2. 第一组数据D1与向量I异或后的结果进行DES加密得到第一组密文C1(注意:这里有向量I的说法,ECB模式下没有使用向量I)
  3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
  4. 之后的数据以此类推,得到Cn
  5. 按顺序连为C1C2C3......Cn即为加密结果。

加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

ECB(电子密码本模式)

电子密本方式,这是JAVA封装的DES算法的默认模式,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,则补足8个字节(注意:这里就涉及到数据补位了)进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

CFB(加密反馈模式)

加密反馈模式克服了需要等待8个字节才能加密的缺点,它采用了分组密码作为流密码的密钥流生成器;

OFB(输出反馈模式)

与CFB模式不同之处在于, 加密位移寄存器与密文无关了,仅与加密key和加密算法有关;
做法是不再把密文输入到加密移位寄存器,而是把输出的分组密文(Oi)输入到一位寄存器;

DES加密之golang的CBC和ECB模式代码实现

CBC和ECB模式加密

func DesECBEncrypt(data, key []byte)([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    data = PKCS5Padding(data, bs)
    if len(data)%bs != 0 {
        return nil, errors.New("Need a multiple of the blocksize")
    }
    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        block.Encrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }
    return out, nil
}

func DesCBCEncrypt(origData, key []byte) ([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    origData = PKCS5Padding(origData, block.BlockSize())
    // origData = ZeroPadding(origData, block.BlockSize())
    blockMode := cipher.NewCBCEncrypter(block, key)
    crypted := make([]byte, len(origData))
    // 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
    // crypted := origData
    blockMode.CryptBlocks(crypted, origData)
    return crypted, nil
}

func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}

CBC和ECB模式解密

func DesECBDecrypt(data, key []byte)([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    bs := block.BlockSize()
    if len(data)%bs != 0 {
        return nil, errors.New("crypto/cipher: input not full blocks")
    }
    out := make([]byte, len(data))
    dst := out
    for len(data) > 0 {
        block.Decrypt(dst, data[:bs])
        data = data[bs:]
        dst = dst[bs:]
    }
    out = PKCS5UnPadding(out)
    return out, nil
}

func DesCBCDecrypt(crypted, key []byte) ([]byte, error) {
    block, err := des.NewCipher(key)
    if err != nil {
        return nil, err
    }
    blockMode := cipher.NewCBCDecrypter(block, key)
    //origData := make([]byte, len(crypted))
    origData := crypted
    blockMode.CryptBlocks(origData, crypted)
    //origData = PKCS5UnPadding(origData)

    origData = PKCS5UnPadding(origData)
    return origData, nil
}

func PKCS5UnPadding(origData []byte) []byte {
    length := len(origData)
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

总结

以需求驱动技术,技术本身没有优略之分,只有业务之分。

推荐阅读:
  1. Redis实战之限制操作频率
  2. 设计模式 之 单例模式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

des ecb cbc

上一篇:php框架laravel 5.1环境构建(CentOS 6.5)之FastCGI

下一篇:打造专业的编译环境(十四)

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》