3DES,对称加密的一种,也称Triple DES,3DES为DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。为了兼容普通的DES,3DES并没有直接使用 加密->加密->加密
的方式,而是采用了加密->解密->加密
的方式。
![](https://img.haomeiwen.com/i6534448/e1193a4a70be9f27.jpg)
当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通DES加密算法的兼容。
![](https://img.haomeiwen.com/i6534448/18aa109c50f8d3b8.jpg)
解密
3DES解密过程,与加密过程相反,即逆序使用密钥。是以密钥3、密钥2、密钥1的顺序执行 解密->加密->解密
。
![](https://img.haomeiwen.com/i6534448/0e7b5ffd49048d43.png)
相比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...)
}
网友评论