其他分享
首页 > 其他分享> > 对称加密的分组加密模式以及go语言实现

对称加密的分组加密模式以及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)
}

  

标签:cipherText,加密,err,分组,key,go,byte
来源: https://www.cnblogs.com/xiaoxiaolinux/p/14778170.html