Go 实现3DES加密解密

3DES,对称加密的一种,也称Triple DES,3DES为DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。为了兼容普通的DES,3DES并没有直接使用 加密->加密->加密 的方式,而是采用了加密->解密->加密 的方式。

image

当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通DES加密算法的兼容。

image

解密

3DES解密过程,与加密过程相反,即逆序使用密钥。是以密钥3、密钥2、密钥1的顺序执行 解密->加密->解密

image

相比DES,3DES因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了AES加密算法,AES较于3DES速度更快、安全性更高。

加密模式

  • 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之间。

代码实现

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

对比DES,3DES只是换了NewTripleDESCipher。不过,需要注意的是,密钥长度必须24byte,否则直接返回错误

package main
​
import (
 "crypto/des"
 "bytes"
 "crypto/cipher"
 "fmt"
)
​
//DES 和 3DES加密区别
//前者 加密  密钥必须是8byte
//后者加密 解密 再加密  密钥必须是24byte
func main() {
 //定义密钥,必须是24byte
 key := []byte("123456789012345678901234")
 //定义明文
 origData := []byte("hello world")
​
 //加密
 en := ThriDESEnCrypt(origData,key)
​
 //解密
 de := ThriDESDeCrypt(en,key)
 fmt.Println(string(de))
}
//解密
func ThriDESDeCrypt(crypted,key []byte)[]byte{
 //获取block块
 block,_ :=des.NewTripleDESCipher(key)
 //创建切片
 context := make([]byte,len(crypted))
​
 //设置解密方式
 blockMode := cipher.NewCBCDecrypter(block,key[:8])
 //解密密文到数组
 blockMode.CryptBlocks(context,crypted)
​
 //去补码
 context = PKCSUnPadding(context)
 return context
}
​
//去补码
func PKCSUnPadding(origData []byte)[]byte{
 length := len(origData)
 unpadding := int(origData[length-1])
 return origData[:length-unpadding]
}
//加密
func ThriDESEnCrypt(origData,key []byte)[]byte{
 //获取block块
 block,_ :=des.NewTripleDESCipher(key)
 //补码
 origData = PKCSPadding(origData, block.BlockSize())
 //设置加密方式为 3DES  使用3条56位的密钥对数据进行三次加密
 blockMode := cipher.NewCBCEncrypter(block,key[:8])
​
 //创建明文长度的数组
 crypted := make([]byte,len(origData))
​
 //加密明文
 blockMode.CryptBlocks(crypted,origData)
​
 return crypted
​
​
}
//补码
func PKCSPadding(origData []byte,blockSize int)[]byte{
 //计算需要补几位数
 padding := blockSize-len(origData)%blockSize
 //在切片后面追加char数量的byte(char)
 padtext := bytes.Repeat([]byte{byte(padding)},padding)
​
 return append(origData,padtext...)
}

你可能感兴趣的:(Go 实现3DES加密解密)