【go密码学】-对称加密算法
对称加密
对称加密算法是相对于非对称加密算法而言,两者的区别在于,对称加密和加密和解密时使用相同的秘钥,而非对称加密在加密和解密时使用不同的秘钥(公钥和私钥)。常见的对称加密算法:DES
、3DES
、AES
。
DES
DES的基础结构,由IBM公司的Horst Feistel设计,因此称Feistel网络。在Feistel网络中,加密的每个步骤称为轮,经过初始置换后的64位明文,进行了16轮Feistel轮的加密过程,最后经过终结置换后形成最终的64位密文,如下图:
go实现DES
package main import ( "bytes" "fmt" "crypto/des" "crypto/cipher" "encoding/base64" ) //利用秘钥通过DES算法实现明文的加密 //利用秘钥通过DES算法实现密文的解密 //在加密和解密之前,首先需要补码和去码的操作 //补码 func PKCS5Padding(orgData []byte, blockSize int) [] byte { //abc55555 padding := blockSize - len(orgData)%8 padtxt := bytes.Repeat([]byte{byte(padding)}, padding) return append(orgData, padtxt...) } //去码 func PKCS5UnPadding(cipherTxt []byte) []byte { length := len(cipherTxt) unpadding := int(cipherTxt[length-1]) return cipherTxt[:length-unpadding] //cipherTxt[:4] } //DES加密,加密会用到补码 func DesEncrypt(orig []byte, key []byte) []byte { //首先检验秘钥是否合法 //DES加密算法,秘钥的长度必须为8bit block.BlockSize() = 8; block, _ := des.NewCipher(key) //补码 origData := PKCS5Padding(orig, block.BlockSize()) //设置加密方式 blockMode := cipher.NewCBCEncrypter(block, key) //加密处理 crypted := make([]byte, len(origData)) //存放加密后的密文 blockMode.CryptBlocks(crypted, origData) return crypted } //DES解密,解密要用到去码 func DesDecrypt(cipherTxt []byte, key []byte) [] byte { //校验key的有效性 block, _ := des.NewCipher(key) //设置解码方式 blockMode := cipher.NewCBCDecrypter(block, key) //创建缓冲,存放解密后的数据 orgData := make([]byte, len(cipherTxt)) //开始解密 blockMode.CryptBlocks(orgData, cipherTxt) //去掉编码 orgData = PKCS5UnPadding(orgData) return orgData } func main() { //pad:=PKCS5Padding([]byte("abcd"),8) //fmt.Println(pad) var cipherTxt = DesEncrypt([]byte("kongyixueyuan"), []byte("12345678")) fmt.Println(cipherTxt) //通过base64处理秘文 fmt.Println(base64.StdEncoding.EncodeToString(cipherTxt)) //解码 var plainText = DesDecrypt(cipherTxt, []byte("12345678")) fmt.Println(string(plainText)) //对称加密中,加密与解密是互逆的 //DES加密中秘钥长度必须为8字节,3DES秘钥长度必须为24,AES加密算法中秘钥长度必须为16或24或32字节 }
- DES加密中秘钥长度必须为8字节
- 在加密前需要补码操作(比如abc加密前,补码到8位:abc55555)
- 在解密后需要去码操作
3DES
DES的56位的秘钥安全性不足,已被证实可以在短时间破解,为解决此问题,出现了3DES。3DES为DES向AES过渡的加密算法,它使用3条56位的秘钥对数据进行3次加密。为兼容普通的DES,3DES并没有直接使用加密->加密->加密
的方式。
加密
当三重秘钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可以实现对普通DES加密算法的兼容。
解密
与加密过程相反,是以秘钥3、秘钥2、秘钥1的顺序执行解密->加密->解密
。
AES
3DES因秘钥长度变长,安全性提升,但处理速度不高。因此又出现了AES加密算法。AES比3DES速度更快,安全性更高。
AES全称Advanced Encryption Standard
,即:高级加密标准。AES加密算法中秘钥长度必须为16或24或32字节
。
go实现aes
package main import ( "crypto/aes" "crypto/cipher" "bytes" "fmt" "encoding/base64" ) //PKCS5的分组是以8为单位 //PKCS7的分组长度为1-255 func PKCS7Padding(org []byte, blockSize int) []byte { pad := blockSize - len(org)%blockSize padArr := bytes.Repeat([]byte{byte(pad)}, pad) return append(org, padArr...) } //通过AES方式解密密文 func PKCS7UnPadding(org []byte) []byte { //abcd4444 l := len(org) pad := org[l-1] //org[0:4] return org[:l-int(pad)] } func AESDecrypt(cipherTxt []byte, key []byte) []byte { block, _ := aes.NewCipher(key) blockMode := cipher.NewCBCDecrypter(block, key) //创建明文缓存 org := make([]byte, len(cipherTxt)) //开始解密 blockMode.CryptBlocks(org, cipherTxt) //去码 org = PKCS7UnPadding(org) //返回明文 return org } //AES加密 func AESEncrypt(org []byte, key [] byte) []byte { //检验秘钥 block, _ := aes.NewCipher(key) //对明文进行补码 org = PKCS7Padding(org, block.BlockSize()) //设置加密模式 blockMode := cipher.NewCBCEncrypter(block, key) //创建密文缓冲区 cryted := make([]byte, len(org)) //加密 blockMode.CryptBlocks(cryted, org) //返回密文 return cryted } func main() { var Encode = AESEncrypt([]byte("kongyixueyuan"), []byte("1234567890123456")) fmt.Println(base64.StdEncoding.EncodeToString(Encode)) fmt.Println("名文为:", string(AESDecrypt([]byte(Encode), []byte("1234567890123456")))) }
分组模式
ECB
:Electronic CodeBook mode (电子密码模式)CBC
:Cipher Block Chaining mode(密码分组链接模式)CFB
:Cipher FeedBack mode (密文反馈模式)OFB
:Output FeedBack mode (输出反馈模式)CTR
:CounTeR mode (计数器模式)
ECB
- ECB模式是所有模式中最简单的一种。ECB的明文分组和密文分组是一一对应关系,因此,如果明文中存在多个相同的明文分组,则这些明文分组最终都会转换成相同的密文分组。这样一来,只要观察一下密文,就可以知道明文中存在怎样的重复组合,并可以以此为线索来破译密码,因此ECB模式是存在风险的。
CBC
- 明文分组在加密之前一定会与“前一个密文分组”进行XOR运算,因此即便明文分组1和2的值是相等的,密文分组1和2也不一定相等,这样ECB模式的缺陷在CBC模式中就不存在了。
- 在CBC模式中,无法单独对一个中间的明文分组进行加密。例如,如果要生成密文分组3,则至少需要凑齐分组1、2、3才行。
- 如果密文分组中有一些比特缺失了,即便只缺失了1比特,那么缺失比特的位置之后的密文分组也就全部无法解密了。
在上述的机密代码中,采用的就是CBC模式加密。
blockMode := cipher.NewCBCEncrypter(block, key)
相关推荐
yedaoxiaodi 2020-06-16
Ghero 2020-06-10
rein0 2020-01-29
seekerhit 2019-12-24
数据与算法之美 2015-03-18
tuonioooo 2015-03-09
微分 2017-01-06
ohhmygod 2013-11-07
daklqw 2019-06-30
dushine00 2019-06-28
wuxiaosi0 2019-06-28
dushine00 2019-06-27
Broadview 2008-04-01
sunjunior 2018-10-17
sunjunior 2020-04-22
Ghero 2017-11-14
yedaoxiaodi 2020-06-28
yishujixiaoxiao 2020-06-03