1、测试框架
package main
import "fmt"
/*需求:
算法:DES
密钥:8bytes
分组长度:8bytes
分组:CBC
1、提供初始化向量,长度与分组相同,8bytes
2、需要填充
加密分析
1、创建并返回一个使用DES算法的cipher.Block接口。
func NewCipher(key []byte) (cipher.Block, error)
-包名:des
-参数:key 密钥,8bytes
-返回值:一个cipher.Block接口
type Block interface {
// 返回加密字节块的大小.
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
2、进行数据填充
//TODO
3、引入CBC模式
返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
func NewCBCEncrypter(b Block, iv []byte) BlockMode
-包名:cipher
-参数1:cipher.Block
-参数2:iv,initialize vector
-返回值:分组模式,里面提供加解密方法
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
解密分析
*/
//输入明文、密钥,输出密文
func desCBCEncrtpt(src, key []byte)[]byte{
//TODO
fmt.Printf("加密开始,输入的数据为:%s\n",src)
fmt.Printf("加密结束,加密数据为:%x\n",key)
return []byte{}
}
func main() {
src := []byte("12345678")
key := []byte("12345678")
cipherData := desCBCEncrtpt(src,key)
fmt.Printf("cipherData:%x\n",cipherData)
}
2、无填充的实现
package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"fmt"
)
//输入明文、密钥,输出密文
func desCBCEncrtpt(src, key []byte)[]byte{
//TODO
fmt.Printf("加密开始,输入的数据为:%s\n",src)
// 1、创建并返回一个使用DES算法的cipher.Block接口。
block,err := des.NewCipher(key)
if err != nil{
panic(err)
}
//2、进行数据填充
//TODO
//3、引入CBC
// 返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
iv := bytes.Repeat([]byte("1"),block.BlockSize()) //将[]byte("1")重复block.BlockSize()次
blockMode := cipher.NewCBCEncrypter(block , iv)
//4、加密操作
blockMode.CryptBlocks(src,src) //参数1:密文 参数2:明文
fmt.Printf("加密结束,加密数据为:%x\n",src)
return src
}
func main() {
src := []byte("12345678")
key := []byte("12345678")
cipherData := desCBCEncrtpt(src,key)
fmt.Printf("cipherData:%x\n",cipherData)
}
3、填充逻辑
填充的时候,根据所需要填充的数量进行填充,需要填充5个字符时,会创建一个5个“5”的数组,追加到原始数据的后面
//填充函数
//参数1:原始数据;参数2:原始数据的长度
func paddingInfo(src []byte,blockSize int) []byte {
// 1、得到明文长度
length := len(src)
// 2、需要填充的长度
remains := length % blockSize
paddingNumber := blockSize - remains
// 3、把填充的数值转换为字符
s1 := byte(paddingNumber)
// 4、把字符拼成数组
s2 := bytes.Repeat([]byte{s1},paddingNumber)
// 5、把拼成的数组追加到src返回新的数字
srcNew := append(src,s2...)
// 6、返回
return srcNew
}
4、解密(无去除)
/*解密分析
1、创建并返回一个使用DES算法的cipher.Block接口。
func NewCipher(key []byte) (cipher.Block, error)
-包名:des
-参数:key 密钥,8bytes
-返回值:一个cipher.Block接口
type Block interface {
// 返回加密字节块的大小.
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
2、引入CBC模式
返回一个密码分组链接模式的、底层用b解密的BlockMode接口,初始向量iv必须和加密时使用的iv相同。
func NewCBCDecrypter(b Block, iv []byte) BlockMode
-包名:cipher
-参数1:cipher.Block
-参数2:iv,initialize vector
-返回值:分组模式,里面提供加解密方法
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
3、解密操作
4、去除填充
*/
func desCBCDecrtpt(cipherData, key []byte)[]byte{
fmt.Printf("解密开始,输入的数据为:%x\n",cipherData)
// 1、创建并返回一个使用DES算法的cipher.Block接口。
block,err := des.NewCipher(key)
if err != nil{
panic(err)
}
//2、引入CBC
// 返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
iv := bytes.Repeat([]byte("1"),block.BlockSize()) //将[]byte("1")重复block.BlockSize()次
blockMode := cipher.NewCBCDecrypter(block , iv)
//3、解密操作
blockMode.CryptBlocks(cipherData,cipherData) //参数1:明文文 参数2:密文
fmt.Printf("解密结束,解密数据为:%s\n",cipherData)
//4、去除填充
//TODO
return cipherData
}
附:完整思路与程序
package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"fmt"
)
/*需求:
算法:DES
密钥:8bytes
分组长度:8bytes
分组:CBC
1、提供初始化向量,长度与分组相同,8bytes
2、需要填充
加密分析
1、创建并返回一个使用DES算法的cipher.Block接口。
func NewCipher(key []byte) (cipher.Block, error)
-包名:des
-参数:key 密钥,8bytes
-返回值:一个cipher.Block接口
type Block interface {
// 返回加密字节块的大小.
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
2、进行数据填充
//TODO
3、引入CBC模式
返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
func NewCBCEncrypter(b Block, iv []byte) BlockMode
-包名:cipher
-参数1:cipher.Block
-参数2:iv,initialize vector
-返回值:分组模式,里面提供加解密方法
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
解密分析
1、创建并返回一个使用DES算法的cipher.Block接口。
func NewCipher(key []byte) (cipher.Block, error)
-包名:des
-参数:key 密钥,8bytes
-返回值:一个cipher.Block接口
type Block interface {
// 返回加密字节块的大小.
BlockSize() int
// 加密src的第一块数据并写入dst,src和dst可指向同一内存地址
Encrypt(dst, src []byte)
// 解密src的第一块数据并写入dst,src和dst可指向同一内存地址
Decrypt(dst, src []byte)
}
2、引入CBC模式
返回一个密码分组链接模式的、底层用b解密的BlockMode接口,初始向量iv必须和加密时使用的iv相同。
func NewCBCDecrypter(b Block, iv []byte) BlockMode
-包名:cipher
-参数1:cipher.Block
-参数2:iv,initialize vector
-返回值:分组模式,里面提供加解密方法
type BlockMode interface {
// 返回加密字节块的大小
BlockSize() int
// 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址
CryptBlocks(dst, src []byte)
}
3、解密操作
4、去除填充
*/
//输入明文、密钥,输出密文
func desCBCEncrtpt(src, key []byte)[]byte{
fmt.Printf("加密开始,输入的数据为:%s\n",src)
// 1、创建并返回一个使用DES算法的cipher.Block接口。
block,err := des.NewCipher(key)
if err != nil{
panic(err)
}
//2、进行数据填充
//TODO
src = paddingInfo(src,block.BlockSize())
//3、引入CBC
// 返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
iv := bytes.Repeat([]byte("1"),block.BlockSize()) //将[]byte("1")重复block.BlockSize()次
blockMode := cipher.NewCBCEncrypter(block , iv)
//4、加密操作
blockMode.CryptBlocks(src,src) //参数1:密文 参数2:明文
return src
}
//填充函数
func paddingInfo(src []byte,blockSize int) []byte {
// 1、得到明文长度
length := len(src)
// 2、需要填充的长度
remains := length % blockSize
paddingNumber := blockSize - remains
// 3、把填充的数值转换为字符
s1 := byte(paddingNumber)
// 4、把字符拼成数组
s2 := bytes.Repeat([]byte{s1},paddingNumber)
// 5、把拼成的数组追加到src返回新的数字
srcNew := append(src,s2...)
// 6、返回
return srcNew
}
func main() {
src := []byte("不是一番寒彻骨,哪得梅花扑鼻香!")
key := []byte("12345678")
//调用加密函数
cipherData := desCBCEncrtpt(src,key)
fmt.Printf("cipherData:%x\n",cipherData)
//调用解密函数
plainText := desCBCDecrtpt(cipherData,key)
fmt.Printf("decodeData:%s\n",plainText)
}
func desCBCDecrtpt(cipherData, key []byte)[]byte{
fmt.Printf("解密开始,输入的数据为:%x\n",cipherData)
// 1、创建并返回一个使用DES算法的cipher.Block接口。
block,err := des.NewCipher(key)
if err != nil{
panic(err)
}
//2、引入CBC
// 返回一个密码分组链接模式的、底层用b加密的BlockMode接口,初始向量iv的长度必须等于b的块尺寸。
iv := bytes.Repeat([]byte("1"),block.BlockSize()) //将[]byte("1")重复block.BlockSize()次
blockMode := cipher.NewCBCDecrypter(block , iv)
//3、解密操作
blockMode.CryptBlocks(cipherData,cipherData) //参数1:明文文 参数2:密文
//4、去除填充
plainText := unpaddingInfo(cipherData)
return plainText
}
//去除重复
func unpaddingInfo(plainTexe []byte) []byte{
//1、获取长度
length := len(plainTexe)
if length == 0 {
return []byte{}
}
//2、获取最后一个字符
lastByte := plainTexe[length-1]
//3、将字符转成数字
unpaddingNumber := int(lastByte)
//4、切片获取
return plainTexe[:length-unpaddingNumber]
}