版权声明:本文为作者原创,如需转载,请注明出处
https://blog.csdn.net/weixin_42940826
注:分组加密算法需要用分组模式的知识,在我上一篇帖子里有具体介绍,欢迎来戳对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)
DES – Data Encryption Standard
(已经被破解不再使用,但是很有研究价值,而且诞生出了3DES还可以使用)
常见问题
Q1 :是不是分组密码?
A :是, 先对数据进行分组, 然后在加密或解密
Q2:DES的分组长度?
A:8byte == 64bit
Q3: DES的秘钥长度?
A:56bit秘钥长度+8bit错误检测标志位 = 8byte == 64bit
接下来我们使用CBC分组模式实现DES的加密解密(一种常用且需要填充的分组模式)
package main
import (
"bytes"
"crypto/des"
"crypto/cipher"
"fmt"
)
//首先需要一个填充函数,确保长度是模块长度的整数倍
func Padding(blockSize int,plainText []byte)[]byte {
//计算当前明文字节数除以模块长度的余数
yu:=len(plainText)%blockSize
//需要填充的长度即为模块长度减去余数
needlen:=blockSize-yu
//得到填充的字符
//为了方便解密时的去填充操作,我们将填充的字符设置为填充长度
needbytes:=bytes.Repeat([]byte{byte(needlen)},needlen)
newPlaintext:=append(plainText,needbytes...)
return newPlaintext
}
//再来一个解密时所需的去填充函数,和填充函数同理,不做过多注释
func Unpadding(plainText []byte)[]byte {
needlen:=plainText[len(plainText)-1]
return plainText[:len(plainText)-int(needlen)]
}
//CBC模式下的DES加密函数
func DES_CBC_encrypter(key []byte,plainText []byte)[]byte {
//DES算法的模块大小为8,这是固定的,不能改变
blockSize:=8
//启用我们的填充函数,为加密做好准备
newPlaintext:=Padding(blockSize,plainText)
//指定一个DES算法,需要的参数是秘钥,秘钥长度为8位,返回一个cipher.Block接口
block,_:=des.NewCipher(key)
//此函数需要一个iv值,长度要跟秘钥长度相等,即8位,内容随意,但解密时需要相同的iv
iv:=[]byte("thisisiv")
//指定CBC的分组模式,所需参数为前面得到的cipher.Block接口,再次返回一个blockmode接口
blockmode:=cipher.NewCBCEncrypter(block,iv)
//算法和分组模式都指定完毕了,开始计算
//所需两个参数,一个是用来存放加密后的密文,另一个是填充好了的明文,两文长度是一样的
cipherText:=make([]byte,len(newPlaintext))
blockmode.CryptBlocks(cipherText,newPlaintext)
return cipherText
}
func main() {
//设置秘钥和明文,进行加密调用打印到屏幕上
key:=[]byte("thisiske")
plainText:=[]byte("ThisIsPlaintext")
cipherText:=DES_CBC_encrypter(key,plainText)
fmt.Println(cipherText)
}
//执行得到看不懂的结果
以上为DES加密操作,解密操作大同小异,下面直接给出代码
func DES_CBC_decrypter(key []byte,cipherText []byte)[]byte{
block,_:=des.NewCipher(key)
//需要和加密时一样的iv
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCDecrypter(block,iv)
plainText:=make([]byte,len(cipherText))
blockmode.CryptBlocks(plainText,cipherText)
//最后不要忘了去填充
return Unpadding(plainText)
}
DES已经可以在短时间内被暴力破解了,所以3DES应运而生
三重DES (Triple-DES),顾名思义,就是将DES算法重复三次,所得到的算法,也叫TDEA,下图直接明了的阐释了3DES的具体实现方法。
常见问题
Q1:3DES安全吗?
A:安全, 但是效率低
Q2:是不是分组密码,需不需要填充?
A:是,需要,DES怎么填充他还是怎么填充
Q3:3DES分组长度?
A:8字节,因为进行三次操作,每次操作内部还是和DES一样的
Q4:3DES秘钥长度?
A:24字节, 在算法内部会被平均分成3份
代码实现,填充函数我们可以直接调用上面已经封装好的Padding,就不重复给出了
package main
import (
"bytes"
"crypto/des"
"crypto/cipher"
"fmt"
)
//首先需要一个填充函数,确保长度是模块长度的整数倍
func Padding(blockSize int,plainText []byte)[]byte {
//计算当前明文字节数除以模块长度的余数
yu:=len(plainText)%blockSize
//需要填充的长度即为模块长度减去余数
needlen:=blockSize-yu
//得到填充的字符
//为了方便解密时的去填充操作,我们将填充的字符设置为填充长度
needbytes:=bytes.Repeat([]byte{byte(needlen)},needlen)
newPlaintext:=append(plainText,needbytes...)
return newPlaintext
}
//再来一个解密时所需的去填充函数,和填充函数同理,不做过多注释
func Unpadding(plainText []byte)[]byte {
needlen:=plainText[len(plainText)-1]
return plainText[:len(plainText)-int(needlen)]
}
func CBC_3DES_encrypter(key []byte,plainText []byte)[]byte {
BlockSize:=8
newPlaintext:=Padding(BlockSize,plainText)
block,_:=des.NewTripleDESCipher(key)
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCEncrypter(block,iv)
cipherText:=make([]byte,len(newPlaintext))
blockmode.CryptBlocks(cipherText,newPlaintext)
return cipherText
}
func CBC_3DES_decrypter(key []byte,cipherText []byte)[]byte {
block,_:=des.NewTripleDESCipher(key)
iv:=[]byte("thisisiv")
blockmode:=cipher.NewCBCDecrypter(block,iv)
buf:=make([]byte,len(cipherText))
blockmode.CryptBlocks(buf,cipherText)
return Unpadding(buf)
}
func main() {
key:=[]byte("TheLengthOfKeyOf3desIs24")
plainText:=[]byte("IamThePlaintext00")
cipherText:=CBC_3DES_encrypter(key,plainText)
fmt.Println(cipherText)
result:=CBC_3DES_decrypter(key,cipherText)
fmt.Println(string(result))
}
其实实现起来和DES的实现没什么区别,唯一的区别就是秘钥的长度为3*8=24
相关链接
对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)
CTR分组模式实现的AES加密解密
欢迎交流:)