美文网首页Go知识库
Go 实现 DES 加密和解密

Go 实现 DES 加密和解密

作者: Li_MAX | 来源:发表于2018-05-16 23:59 被阅读121次

    DES加密算法,为对称加密算法中的一种。是以64比特的明文为一个单位来进行加密,超过64比特的数据,要求按固定的64比特的大小分组,分组有很多模式。DES使用的密钥长度为64比特,但由于每隔7个比特设置一个奇偶校验位,因此其密钥长度实际为56比特。奇偶校验为最简单的错误检测码,即根据一组二进制代码中1的个数是奇数或偶数来检测错误。

    加密模式

    • ECB模式 全称Electronic Codebook模式,译为电子密码本模式
    • CBC模式 全称Cipher Block Chaining模式,译为密文分组链接模式
    • CFB模式 全称Cipher FeedBack模式,译为密文反馈模式
    • OFB模式 全称Output Feedback模式,译为输出反馈模式。
    • CTR模式 全称Counter模式,译为计数器模式。

    填充方式

    当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组长度。

    • NoPadding
      API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim
    • PKCS5Padding
      加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8
      解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。
      加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。
    • PKCS7Padding
      PKCS7Padding 的填充方式和PKCS5Padding 填充方式一样。只是加密块的字节数不同。PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。

    以下是go 实现的DES加密和解密代码:

    本代码采用CBC加密模式,填充方式采用PKCS5Padding

    package main
    ​
    import (
     "crypto/des"
     "bytes"
     "crypto/cipher"
     "fmt"
     "encoding/base64"
    )
    ​
    //DES加密方法
    func MyDESEncrypt (origData,key []byte){
     //将字节秘钥转换成block快
     block,_ := des.NewCipher(key)
     //对明文先进行补码操作
     origData = PKCS5Padding(origData,block.BlockSize())
     //设置加密方式
     blockMode := cipher.NewCBCEncrypter(block,key)
     //创建明文长度的字节数组
     crypted := make([]byte, len(origData))
     //加密明文,加密后的数据放到数组中
     blockMode.CryptBlocks(crypted,origData)
     //将字节数组转换成字符串
     fmt.Println(base64.StdEncoding.EncodeToString(crypted))
    ​
    }
    ​
    //实现明文的补码
    func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
     //计算出需要补多少位
     padding := blockSize - len(ciphertext)%blockSize
     //Repeat()函数的功能是把参数一 切片复制 参数二count个,然后合成一个新的字节切片返回
     // 需要补padding位的padding值
     padtext := bytes.Repeat([]byte{byte(padding)}, padding)
     //把补充的内容拼接到明文后面
     return append(ciphertext,padtext...)
    }
    ​
    //解密
    func MyDESDecrypt(data string, key []byte) {
     //倒叙执行一遍加密方法
     //将字符串转换成字节数组
     crypted,_ := base64.StdEncoding.DecodeString(data)
     //将字节秘钥转换成block快
     block, _ := des.NewCipher(key)
     //设置解密方式
     blockMode := cipher.NewCBCDecrypter(block,key)
     //创建密文大小的数组变量
     origData := make([]byte, len(crypted))
     //解密密文到数组origData中
     blockMode.CryptBlocks(origData,crypted)
     //去补码
     origData = PKCS5UnPadding(origData)
     //打印明文
     fmt.Println(string(origData))
    }
    ​
    //去除补码
    func PKCS5UnPadding(origData []byte) []byte {
     length := len(origData)
     // 去掉最后一个字节 unpadding 次
     unpadding := int(origData[length-1])
     //解密去补码时需取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文
     return origData[:(length - unpadding)]
    }
    ​
    func main () {
    ​
     //定义明文
     data := []byte("hello world")
    ​
     //密钥
     key := []byte("12345678")
    ​
     //加密
     MyDESEncrypt(data,key)
    ​
     //解密
     MyDESDecrypt("CyqS6B+0nOGkMmaqyup7gQ==",key)
    }
    

    其中解密只需把加密过程倒叙走一遍。

    屏幕快照 2018-05-16 下午11.13.08.png

    关于明文补码和去补码操作:

    加密前明文补码规则 (cipher.NewCBCEncrypter 调用前操作):

    加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8

    对应的明文补码代码部分:

    //实现明文的补码
    func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
     //计算出需要补多少位
     padding := blockSize - len(ciphertext)%blockSize
     //Repeat()函数的功能是把参数一 切片复制 参数二count个,然后合成一个新的字节切片返回
     // 需要补padding位的padding值
     padtext := bytes.Repeat([]byte{byte(padding)}, padding)
     //把补充的内容拼接到明文后面
     return append(ciphertext,padtext...)
    }
    

    解密后去除补码规则(cipher.NewCBCDecrypter调用解密完成后):

    解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。

    对应的去补码代码部分:

    //去除补码
    func PKCS5UnPadding(origData []byte) []byte {
     length := len(origData)
     // 去掉最后一个字节 unpadding 次
     unpadding := int(origData[length-1])
     //解密去补码时需取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文
     return origData[:(length - unpadding)]
    }
    

    相关文章

      网友评论

        本文标题:Go 实现 DES 加密和解密

        本文链接:https://www.haomeiwen.com/subject/hrdvdftx.html