Broadview 2019-06-28
对称加密算法是相对于非对称加密算法而言,两者的区别在于,对称加密和加密和解密时使用相同的秘钥,而非对称加密在加密和解密时使用不同的秘钥(公钥和私钥)。常见的对称加密算法:DES
、3DES
、AES
。
DES的基础结构,由IBM公司的Horst Feistel设计,因此称Feistel网络。在Feistel网络中,加密的每个步骤称为轮,经过初始置换后的64位明文,进行了16轮Feistel轮的加密过程,最后经过终结置换后形成最终的64位密文,如下图:
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的56位的秘钥安全性不足,已被证实可以在短时间破解,为解决此问题,出现了3DES。3DES为DES向AES过渡的加密算法,它使用3条56位的秘钥对数据进行3次加密。为兼容普通的DES,3DES并没有直接使用加密->加密->加密
的方式。
加密
当三重秘钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可以实现对普通DES加密算法的兼容。
解密
与加密过程相反,是以秘钥3、秘钥2、秘钥1的顺序执行解密->加密->解密
。
3DES因秘钥长度变长,安全性提升,但处理速度不高。因此又出现了AES加密算法。AES比3DES速度更快,安全性更高。
AES全称Advanced Encryption Standard
,即:高级加密标准。AES加密算法中秘钥长度必须为16或24或32字节
。
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 (计数器模式)在上述的机密代码中,采用的就是CBC模式加密。
blockMode := cipher.NewCBCEncrypter(block, key)