cbc加密模式(链密码模式)
package main
import (
"bytes"
"crypto/cipher"
"crypto/des"
"fmt"
"log"
)
const (
//定义密钥
key = "1234abcd"
//定义向量
iv = "12345678"
)
//分组填充
func GroupFill(plaintext []byte) []byte {
//计算分组后需要填充的字节数;
//如果字节不足8个,需要填充不足的字节数,比如不足字节数为3个,则填充[3,3,3];
//如果字节刚好是8的倍数,则需要填充8个字节,如[8,8,8,8,8,8,8,8]
//这样在解码删除时,就可以根据最后一个数确定删除的字节数
fillCount := des.BlockSize - len(plaintext) % des.BlockSize
//将int类型的变量fillCount添加到[]byte
bt := []byte{byte(fillCount)}
//将字节重复fillCount次
fillByte := bytes.Repeat(bt, fillCount)
//将填充的字节添加到名文当中
plaintext = append(plaintext, fillByte...)
fmt.Println(bt, plaintext)
return plaintext
}
//加密
func DesEnc(plaintext []byte) []byte {
var(
block cipher.Block
err error
)
//创建des
if block, err = des.NewCipher([]byte(key)); err != nil{
log.Fatal(err)
}
//创建cbc加密模式(链密码模式)
blockMode := cipher.NewCBCEncrypter(block, []byte(iv))
//明文加密,src和dst可指向同一内存地址
blockMode.CryptBlocks(plaintext, plaintext)
return plaintext
}
//解密
func DesDec(ciptext []byte) []byte {
var(
block cipher.Block
err error
)
//创建des
if block, err = des.NewCipher([]byte(key)); err != nil{
log.Fatal(err)
}
//创建cbc解密模式
blockMode := cipher.NewCBCDecrypter(block, []byte(iv))
//解密
blockMode.CryptBlocks(ciptext, ciptext)
count := len(ciptext)
//减去填充的字节
ciptext = ciptext[:count-int(ciptext[count-1])]
return ciptext
}
func main() {
//定义明文
plaintext := []byte("好好学习,天天向上")
fmt.Println("明文", string(plaintext))
//填充分组
plaintext = GroupFill(plaintext)
//加密
ciptext := DesEnc(plaintext)
fmt.Println("密文", ciptext)
//解密
plaintext = DesDec(ciptext)
fmt.Println("解密", string(plaintext))
}说明:
- 对称加密:加密和解密使用相同的密钥
- des加密方式需要以8个字节为一组进行加密
- cbc链密码模式需要对分组进行填充
- cbc加密模式需要向量IV 和明文分组做按位异或(XOR)运算然后加密,如下图: