go 对称加密算法des

2,142 阅读1分钟

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))

}

说明: 

  1. 对称加密:加密和解密使用相同的密钥
  2. des加密方式需要以8个字节为一组进行加密
  3. cbc链密码模式需要对分组进行填充
  4. cbc加密模式需要向量IV 和明文分组做按位异或(XOR)运算然后加密,如下图: