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

对称加密算法

DES

Data Encryption Standard (数据加密标准)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码。DES一直以来被美国以及其他国家的政府和银行等广泛应用,然而,随着计算机的进步,现在DES已经能够本暴力破解,强度大不如以前了。

RSA公司举办过破译DES密钥的比赛(DESChallenge),比赛的结果为:

  • 1977年比赛中用了96天破解
  • 1998年第一次比赛用了41天破解
  • 1998年第二次比赛用了56小时
  • 1999年第三次比赛中只用了22小时15分钟就被破解了

由于DES的密文可以在短时间内被破解,因此除了它来解密以前的密文外,现在我们不应该使用该算法了,不安全。

DES的加密解密

DES时一种将64比特的明文加密成64比特的密文的对称密码算法,它的密钥长度是56比特,尽管从规格上来说,DES的密钥长度是64比特,但由于每隔7比特会设置一个用于错误检查的比特,因此实质上其密钥长度是56比特。

总结:

  • 现在使用DES方式加密,数据还安全吗?
    • 不安全,已经被破解
  • 是不是分组密码?
    • 是,先对数据进行分组,然后再加密或解密
  • DES的分组长度?
    • 8byte==64bit
  • DES 的秘钥长度?
    • 56bit秘钥长度+8bit错误检查标志位=64bit==8byte
3DES

Triple-DES,三重DES–使用DES三次加密

总结:

  • 3DES安全吗?
    • 安全,但是效率低
  • 算法描述?
    • 进行了三次DES加密
  • 是不是分组算法?
  • 3DES分组长度?
    • 8byte
  • 3DES秘钥长度?
    • 24byte,在算法内部会被平均分成3份,目的是兼容DES
  • 3DES加密过程?
    • 秘钥1->加密->,秘钥2->解密,秘钥3->加密
  • 3DES解密过程?
    • 秘钥1->解密->,秘钥2->加密,秘钥3->解密

DES-CBC模式加解密Go实现

package main

import (
	"crypto/cipher"
	"crypto/des"
)

//明文数据填充
func paddingLastGroup(plainText []byte, blockSize int) []byte {
	//1.计算最后一个分组中明文后需要填充的字节数
	padNum := blockSize - len(plainText)%blockSize
	//2.将字节数转换为byte类型
	char := []byte{byte(padNum)}
	//3.创建切片并初始化
	newPlain := bytes.Repeat(char, padNum)
	//4.将填充数据追加到原始数据后
	newText := append(plainText, newPlain...)

	return newText
}

//去掉明文后面的填充数据
func unpaddingLastGroup(plainText []byte) []byte {
	//1.拿到切片中的最后一个字节
	length := len(plainText)
	lastChar := plainText[length-1]
	//2.将最后一个数据转换为整数
	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.填充明文数据(这里必须填充,不管原始明文是否能被块长度整除)
	groupData := paddingLastGroup(plainText, block.BlockSize())
	//3.选择加密模式
	iv := []byte("12345678")
	blockMode := cipher.NewCBCEncrypter(block, iv)
	//4.加密
	cipherText := make([]byte, len(groupData))
	blockMode.CryptBlocks(cipherText, groupData)
	//blockMode.CryptBlocks(groupData, groupData) //这样也可以,官方文档中说明传入传出参数可指向同一地址
	return cipherText
}

//des解密
func desDecrypt(cipherText, key []byte) []byte {
	//1.创建一个des底层密码接口
	block, err := des.NewCipher(key)
	if err != nil {
		panic(err)
	}
	//2.选择解密模式
	iv := []byte("12345678") //初始化向量必须和加密时的一样
	blockMode := cipher.NewCBCDecrypter(block, iv)
	//3.解密
	padText := make([]byte, len(cipherText))
	blockMode.CryptBlocks(padText, cipherText)
	//4.去填充数据
	plainText := unpaddingLastGroup(padText)
	return plainText
}

func main(){
	fmt.Println("des 加解密")
	key := []byte("1q2w3e4r")
	src := []byte("DES  --Data Encryption Standard (数据加密标准)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码。DES一直以来被美国以及其他国家的政府和银行等广泛应用,然而,随着计算机的进步,现在DES已经能够本暴力破解,强度大不如以前了。由于DES的密文可以在短时间内被破解,因此除了它来解密以前的密文外,现在我们不应该使用该算法了,不安全。")
	cipherText := desEncrypt(src, key)
	plainText := desDecrypt(cipherText, key)
	fmt.Println("解密后的数据为:", string(plainText))
}
AES

Advanced Encryption Standard(高级加密标准),AES是取代DES的一种对称密码算法,底层算法为Rijndael,该底层算法是有比利时密码学家设计的分组密码算法。

Rijndael的分组长度为128比特,密钥长度可以以32比特为单位在128比特到256比特的范围内进行选择,在AES的规格中,密钥长度只有128、192、256比特三种

128bit = 16字节

192bit = 24字节

256bit = 32字节

在go提供的接口中只支持16字节长度的密钥长度

总结:

  • AES安全吗?
    • 安全,效率高,推荐使用
  • 是不是分组密码?
  • AES分组长度?
    • 128bit = 16字节
  • AES密钥长度?
    • 128bit = 16字节
    • 192bit = 24字节
    • 256bit = 32字节
    • 在go提供的接口中只支持16字节

AES-CTR模式加解密Go实现

package main

import (
	"crypto/aes"
	"crypto/cipher"
)

//aes加密
func aesEncrypt(plainText, key []byte) []byte {
	//1.建立一个底层使用的aes密码接口
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	//2.ctr模式不需要数据填充
	//3.选择加密模式
	iv := []byte("12345678qwertyui")  //不需要初始化向量,go接口中的iv可以理解为随机数种子,iv的长度等于明文分组长度,并不是真正的初始化向量
	stream := cipher.NewCTR(block, iv)
	//4.加密
	stream.XORKeyStream(plainText, plainText)
	return plainText
}

//aes解密
func aesDecrypt(cipherText, key []byte) []byte {
	//1.创建一个aes底层密码接口
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	//2.选择解密模式
	iv := []byte("12345678qwertyui") //随机数种子,长度为16位
	stream := cipher.NewCTR(block, iv)
	//3.解密
	padText := make([]byte, len(cipherText))
	stream.XORKeyStream(padText, cipherText)
	return padText
}

func main(){
	fmt.Println("aes 加解密")
	key := []byte("1q2w3e4r")
	src := []byte("AES  --Advanced Encryption Standard(高级加密标准)\nAES是取代DES的一种对称密码算法,底层算法为Rijndael,该底层算法是有比利时密码学家设计的分组密码算法。\nRijndael的分组长度为128比特,密钥长度可以以32比特为单位在128比特到256比特的范围内进行选择,在AES的规格中,密钥长度只有128、192、256比特三种,在go提供的接口中只支持16字节长度的密钥长度,加密和解密的函数接口是一个,原因是异或一次就是加密,异或两次就是解密,因此没必要实现为两个接口")
	cipherText := desEncrypt(src, key)
	plainText := desDecrypt(cipherText, key)
	fmt.Println("解密后的数据为:", string(plainText))
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值