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]
}