对称加密

1、编码
2、DES
2.1、什么事DES
2.2、 加密和解密
2.3、DES的加密与解密 - 图例

2.4、DES在go代码实现
package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
"fmt"
)
func main() {
// 加密
key := []byte("11111111")
result := DesEncrypt_CBC([]byte("yesyes hello world"), key)
fmt.Println(base64.StdEncoding.EncodeToString(result))
// 解密
result = DesDecrypt_CBC(result, key)
fmt.Println("解密之后的数据: ", string(result))
}
// DesEncrypt_CBC src -> 要加密的明文
// key -> 秘钥, 大小为: 8byte
func DesEncrypt_CBC(src, key []byte) []byte {
// 1. 创建并返回一个使用DES算法的cipher.Block接口
block, err := des.NewCipher(key)
// 2. 判断是否创建成功
if err != nil {
panic(err)
}
// 3. 对最后一个明文分组进行数据填充
src = PKCS5Padding(src, block.BlockSize())
// 4. 创建一个密码分组为链接模式的, 底层使用DES加密的BlockMode接口
// 参数iv的长度, 必须等于b的块尺寸
tmp := []byte("helloAAA")
blackMode := cipher.NewCBCEncrypter(block, tmp)
// 5. 加密连续的数据块
dst := make([]byte, len(src))
blackMode.CryptBlocks(dst, src)
fmt.Println("加密之后的数据: ", dst)
// 6. 将加密数据返回
return dst
}
// DesDecrypt_CBC src -> 要解密的密文
// key -> 秘钥, 和加密秘钥相同, 大小为: 8byte
func DesDecrypt_CBC(src, key []byte) []byte {
// 1. 创建并返回一个使用DES算法的cipher.Block接口
block, err := des.NewCipher(key)
// 2. 判断是否创建成功
if err != nil {
panic(err)
}
// 3. 创建一个密码分组为链接模式的, 底层使用DES解密的BlockMode接口
tmp := []byte("helloAAA")
blockMode := cipher.NewCBCDecrypter(block, tmp)
// 4. 解密数据
dst := src
blockMode.CryptBlocks(src, dst)
// 5. 去掉最后一组填充的数据
dst = PKCS5UnPadding(dst)
// 6. 返回结果
return dst
}
// PKCS5Padding 使用pks5的方式填充
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
// 1. 计算最后一个分组缺多少个字节
padding := blockSize - (len(ciphertext) % blockSize)
// 2. 创建一个大小为padding的切片, 每个字节的值为padding
padText := bytes.Repeat([]byte{byte(padding)}, padding)
// 3. 将padText添加到原始数据的后边, 将最后一个分组缺少的字节数补齐
newText := append(ciphertext, padText...)
return newText
}
// PKCS5UnPadding 删除pks5填充的尾部数据
func PKCS5UnPadding(origData []byte) []byte {
// 1. 计算数据的总长度
length := len(origData)
// 2. 根据填充的字节值得到填充的次数
number := int(origData[length-1])
// 3. 将尾部填充的number个字节去掉
return origData[:(length - number)]
}
3、三重DES


3.1 三重DES在go中实现
package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
"fmt"
)
func main() {
// 加密
key := []byte("111111112222222233333333")
result := TripleDESEncrypt([]byte("yesyes hello world"), key)
fmt.Println(base64.StdEncoding.EncodeToString(result))
// 解密
result = TripleDESDecrypt(result, key)
fmt.Println("解密之后的数据: ", string(result))
}
// TripleDESEncrypt 3DES加密
func TripleDESEncrypt(src, key []byte) []byte {
// 1. 创建并返回一个使用3DES算法的cipher.Block接口
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
// 2. 对最后一组明文进行填充
src = PKCS5Padding(src, block.BlockSize())
// 3. 创建一个密码分组为链接模式, 底层使用3DES加密的BlockMode模型
blockMode := cipher.NewCBCEncrypter(block, key[:8])
// 4. 加密数据
dst := src
blockMode.CryptBlocks(dst, src)
return dst
}
// TripleDESDecrypt 3DES解密
func TripleDESDecrypt(src, key []byte) []byte {
// 1. 创建3DES算法的Block接口对象
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
// 2. 创建密码分组为链接模式, 底层使用3DES解密的BlockMode模型
blockMode := cipher.NewCBCDecrypter(block, key[:8])
// 3. 解密
dst := src
blockMode.CryptBlocks(dst, src)
// 4. 去掉尾部填充的数据
dst = PKCS5UnPadding(dst)
return dst
}
// PKCS5Padding 使用pks5的方式填充
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
// 1. 计算最后一个分组缺多少个字节
padding := blockSize - (len(ciphertext) % blockSize)
// 2. 创建一个大小为padding的切片, 每个字节的值为padding
padText := bytes.Repeat([]byte{byte(padding)}, padding)
// 3. 将padText添加到原始数据的后边, 将最后一个分组缺少的字节数补齐
newText := append(ciphertext, padText...)
return newText
}
// PKCS5UnPadding 删除pks5填充的尾部数据
func PKCS5UnPadding(origData []byte) []byte {
// 1. 计算数据的总长度
length := len(origData)
// 2. 根据填充的字节值得到填充的次数
number := int(origData[length-1])
// 3. 将尾部填充的number个字节去掉
return origData[:(length - number)]
}
4、AES
4.1、AES的加密和解密

4.2、 Go中对AES的使用
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
func main() {
key := []byte("1234567812345678")
result := AESEncrypt([]byte("yesyes hello world"), key)
fmt.Println(base64.StdEncoding.EncodeToString(result))
result = AESDecrypt(result, key)
fmt.Println("解密之后的数据: ", string(result))
}
func AESEncrypt(src, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
src = PKCS5Padding(src, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
dst := src
blockMode.CryptBlocks(dst, src)
return dst
}
func AESDecrypt(src, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
dst := src
blockMode.CryptBlocks(dst, src)
dst = PKCS5UnPadding(dst)
return dst
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - (len(ciphertext) % blockSize)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
newText := append(ciphertext, padText...)
return newText
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
number := int(origData[length-1])
return origData[:(length - number)]
}
5、应选择哪种对称加密
5、应选择哪种对称加密