一、对称加密概述
我们在开发中常会遇到这种需求:通信的两端需要传输安全级别较高的数据,这需要我们传输的加密数据既要难以破解,又要可逆的解密过程。哈希算法虽难以破解,但并非适用于通信中的加解密传输。这就需要基于秘钥管理的加密技术了。对称加密是最简单快速的加密方式,所谓对称加密,即加解密双方都掌握相同的秘钥,通过同一秘钥完成加解密操作。常用的对称加密算法有:
- DES:Data Encryption Standard,即数据加密标准;
- TDES(TripleDES) :三重DES;
- AES:Rijndael加密法,Advanced Encryption Standard高级加密标准。
Go标准库中的加密相关包都有相应的支持,下面我们来逐一演示:
二、DES对称加密
DES算法原理:明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
所以要实现DES加密需要准备如下要求:
- ==准备一个8字节(64Bit)的秘钥==;
- 原文需要按8字节(64Bit)长度进行分组,共有五种分组模式,此处我们不具体展开,我们用常用的CBC(密码分组链接模式),这种模式需要一个与分组长度相同的初始化向量,有兴趣的可搜索了解其他模式;
- 对末尾的未够8字节的数据进行填充,把原文转为64Bit的整数倍;
- ==实现加密时的未位分组填充算法和解密时的删除密文末尾分组算法。==
以上,秘钥和初始化向量值需要自己管理,末尾分组的填充算法和删除算法需要自己实现。下面我们实现一个填充算法和删除算法:
//填充明文最后一个分组工具方法
//src - 原始数据
//blockSize - 每个分组的数据长度
func paddingBytes(src []byte, blockSize int) []byte {
//1.求出最后一个分组要填充多个字节
padding := blockSize - len(src)%blockSize
//2.创建新的切片,切片的字节数为填充的字节数,并初始化化,每个字节的值为填充的字节数
padBytes := bytes.Repeat([]byte{byte(padding)}, padding)
//3.将创建出的新切片和原始数据进行连接
newBytes := append(src, padBytes...)
//4.返回新的字符串
return newBytes
}
//删除密文末尾分组填充的工具方法
func unPaddingBytes(src []byte) []byte {
//1.求出要处理的切片的长度
l := len(src)
//2.取出最后一个字符,得到其整型值
n := int(src[l-1])
//3.将切片末尾的number个字节删除
return src[:l-n]
}
以上实现思路为:计算出最后一个分组需要填充的字节数(1-8),并把这个数作为需要填充的占位符,再把填充后的分组与源数据拼接就得到待加密的字符串。
Go通过crypto/des包支持DES加密算法:
import (
"bytes"
"crypto/cipher"
"crypto/des"
)
const (
MYKEY = "abcdefgh" //八字节密匙
IV = "aaaabbbb" //CBC模式的初始化向量
)
//使用des进行对称加密
func EncryptDES(src, key []byte) []byte {
//1. 创建并返回一个使用DES算法的cipher.Block接口
bloc