DES-CBC

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]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章