对称加密的分组加密模式以及go语言实现

Posted 潇潇O

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对称加密的分组加密模式以及go语言实现相关的知识,希望对你有一定的参考价值。

分组加密模式

1、ECB(电子密码本模式)

  简单,效率高,有规律容易被破解。最后一个明文分组要填充,如是是DES或者3DES最后一个分组要填充够8字节。AES要填充为16字节。解密后需要删除填充的字节。

  以下为加密过程。解密过程箭头反过来。这种模式非常不安全,目前已经被淘汰。

 

 2、CBC(密码链模式)

  比EBC安全,密文没有规律,需要一个初始化向量(加密解密的初始化向量相同)。最后的明文分组不足8字节或者16字节任然要填充。

  加密过程

 

 解密过程

 

3、CTR(计数器)模式,生成的密文没有规律,对计数器进行加密到得密钥流再与明文分组进行异或运算得到密文分组。对于最后一个明文分组不需要填充,不需要初始化向量。

 

 go语言实现对称加密的流程

  1、创建一个密码接口(DES/3DES/AES)

//DES  ,key是密钥
func NewCipher(key []byte) (cipher.Block, error)
//3DES
func NewTripleDESCipher(key []byte) (cipher.Block, error)
//AES
func NewCipher(key []byte) (cipher.Block, error)

  2、如果选择的分组模式需要对最后一个分组填充,要编写填充函数

  3、创建一个密码分组模式的接口对象(CBC/CTR)

  4、加密-->密文

 DES的CBC模式加解密

func paddingLast(plainText []byte, blockSize int) []byte {
	//1、填充的字节数
	padNum := blockSize - len(plainText)%blockSize

	//创建新的切片
	char := []byte{byte(padNum)}
	newPlain := bytes.Repeat(char, padNum)
	//把切片追加明文的后面
	newPlain = append(plainText, newPlain...)
	return newPlain

}

//去除填充的数据
func RemovePadding(plainText []byte) []byte {
	//1、拿出最后一个字节
	length := len(plainText)
	lastchar := plainText[length-1]
	number := int(lastchar)
	return plainText[:length-number]

}
//des加密
func desEncrypt(plainText, key []byte) []byte {
	//1、创建一个底层使用des加密的接口
	block, err := des.NewCipher(key)
	if err != nil {
		panic(err)
	}
	//2、填充
	newText := paddingLast(plainText, block.BlockSize())
	//3、创建一个使用CBC分组的接口
	iv := []byte("12345678")
	blockMode := cipher.NewCBCEncrypter(block, iv) //iv初始化向量
	//加密
	dst := make([]byte, len(newText))
	blockMode.CryptBlocks(dst, newText)
	return dst
}
func desDecrypt(cipherText, key []byte) []byte {
	block, err := des.NewCipher(key)
	if err != nil {
		panic(err)
	}
	//3、创建一个使用CBC分组的接口
	iv := []byte("12345678")
	blockMode := cipher.NewCBCDecrypter(block, iv) //iv初始化向量
	//解密
	blockMode.CryptBlocks(cipherText, cipherText)
	PlainText := RemovePadding(cipherText)
	return PlainText

}

func main() {
	fmt.Println("des 加密")
	key := []byte("12345qwe")
	src := []byte("hello world nihao shijie haha")
	cipherText := desEncrypt(src, key)
	fmt.Println("密文:", cipherText)

	PlainText := desDecrypt(cipherText, key)
	fmt.Println("明文:", PlainText)
	fmt.Printf("明文:%s", PlainText)
}

 AES加密的CTR模式

//AES加密 CTR模式
func AES_Encrypt(PlainText, key []byte) []byte {
	//1、创建一个底层使用AES的接口
	block, err := aes.NewCipher(key)
	if err != nil {
		panic("err")
	}
	//2、创建一个使用CTR分组的接口
	iv := []byte("12345678asdfghjk")
	stream := cipher.NewCTR(block, iv)
	//3、加密
	cipherText := make([]byte, len(PlainText))
	stream.XORKeyStream(cipherText, PlainText)
	return cipherText
}
func AES_DEcrypto(cipherText, key []byte) []byte {
	block, err := aes.NewCipher(key)
	if err != nil {
		panic("err")
	}
	iv := []byte("12345678asdfghjk")
	stream := cipher.NewCTR(block, iv)

	stream.XORKeyStream(cipherText, cipherText)
	return cipherText
}
func main() {
	key := []byte("12345678qwertyui")   //16字节的密钥
	PlainText := []byte("i am tangxxx haha !")
	cipherText := AES_Encrypt(PlainText, key)
	fmt.Printf("密文:%s\\n", cipherText)
	Text := AES_DEcrypto(cipherText, key)
	fmt.Printf("明文:%s\\n", Text)
}

  

以上是关于对称加密的分组加密模式以及go语言实现的主要内容,如果未能解决你的问题,请参考以下文章

Go语言实现对称加密算法AESDES3DES和非对称加密算法RSA

密码技术--国密SM4分组密码算法及Go语言应用

密码技术--对称加密算法及Go语言应用

go语言 实现对称加密解密算法

分组密码加密模式选择都有哪些?

go加密算法:CBC对称加密--3DES/AES