常用对称加密DES、3DES具体实现

版权声明:本文为作者原创,如需转载,请注明出处
https://blog.csdn.net/weixin_42940826

注:分组加密算法需要用分组模式的知识,在我上一篇帖子里有具体介绍,欢迎来戳对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)


DES简介和实现

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应运而生


3DES简介和实现

三重DES (Triple-DES),顾名思义,就是将DES算法重复三次,所得到的算法,也叫TDEA,下图直接明了的阐释了3DES的具体实现方法。
常用对称加密DES、3DES具体实现_第1张图片
常见问题
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加密解密
欢迎交流:)

你可能感兴趣的:(密码学)