三重DES是为了增强DES的强度,将DES重复3次所得到的一种密码算法
3DES加密机制:
说明:
三重DES解密机制:
des.NewTripleDESCipher(key)
得到一个block接口iv := key[:block.BlockSize()]
//创建CBC加密模式
blockMode := cipher.NewCBCEncrypter(block, iv)
dst := make([]byte, len(src))
//加密
blockMode.CryptBlocks(dst, src)
package main
import (
"crypto/des"
"密码学/utils"
"crypto/cipher"
"fmt"
"encoding/hex"
)
//3des加密
//src:待加密的明文 key:密钥
//返回值:加密之后的密文
func Encrypt3DES(src, key[]byte) []byte {
//创建加密块
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
length := block.BlockSize()
//填充最后一组数据
src = utils.PaddingText(src, length)
//初始化向量
iv := key[:block.BlockSize()]
//创建CBC加密模式
blockMode := cipher.NewCBCEncrypter(block, iv)
dst := make([]byte, len(src))
//加密
blockMode.CryptBlocks(dst, src)
return dst
}
//3des解密
//src:待解密的密文 key:密钥,和加密时使用的密钥相同
//返回值:解密之后的明文
func Decrypt3DES(src, key []byte) []byte {
//创建解密的块
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
//创建CBC解密模式
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
dst := make([]byte, len(src))
//解密
blockMode.CryptBlocks(dst, src)
//去除尾部填充数据
dst = utils.UnPaddingText(dst)
return dst
}
func main() {
key := []byte("1234567887654321aabbccdd")
data := []byte("WEK")
encrypt_msg := Encrypt3DES(data, key)
fmt.Println("encrypt_msg = ", hex.EncodeToString(encrypt_msg))
decrypt_msg := Decrypt3DES(encrypt_msg, key)
fmt.Println("decrypt_msg = ", string(decrypt_msg))
}
读取文件,将文件内容以[]byte格式取出,这样就可以进行3重DES加密,然后再将其保存成一个文件就可以
package main
import (
"crypto/des"
"crypto/cipher"
"密码学/utils"
"fmt"
"bytes"
"io/ioutil"
"strings"
)
const KEY_SIZE = 24
//3des加密
//src:待加密的明文 key:密钥
//返回值:加密之后的密文
func Encrypt3(src, key[]byte) []byte {
//创建加密块
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
length := block.BlockSize()
//填充最后一组数据
src = utils.PaddingText(src, length)
//初始化向量
iv := key[:block.BlockSize()]
//创建CBC加密模式
blockMode := cipher.NewCBCEncrypter(block, iv)
dst := make([]byte, len(src))
//加密
blockMode.CryptBlocks(dst, src)
return dst
}
//3des解密
//src:待解密的密文 key:密钥,和加密时使用的密钥相同
//返回值:解密之后的明文
func Decrypt3(src, key []byte) []byte {
//创建解密的块
block, err := des.NewTripleDESCipher(key)
if err != nil {
panic(err)
}
//创建CBC解密模式
blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
dst := make([]byte, len(src))
//解密
blockMode.CryptBlocks(dst, src)
//去除尾部填充数据
dst = utils.UnPaddingText(dst)
return dst
}
//对用户输入的密钥进行梳理,如果用户输入的密钥太长,
//截取密钥前24字节,如果用户输入的密钥太短,
func genKey(key []byte) []byte {
//创建切片,用于存储最终的密钥
kkey := make([]byte, 0, KEY_SIZE)
length := len(key)
//密钥长度大于24字节
if length > KEY_SIZE {
kkey = append(kkey, key[:KEY_SIZE]...)
}else {
div := KEY_SIZE / length
mod := KEY_SIZE % length
for i := 0; i < div; i++ {
kkey = append(kkey, key...)
}
kkey = append(kkey, key[:mod]...)
}
return kkey
}
func main() {
//命令
var command string
//文件名称
var filename string
fmt.Print("请输入命令(加密|解密):")
fmt.Scanln(&command)
if command == "加密" {
fmt.Print("请输入需要被加密的文件的名称:")
fmt.Scanln(&filename)
var password string
fmt.Println("请输入密钥:")
fmt.Scanln(&password)
var confirmpassword string
fmt.Print("请输入确认密钥:")
fmt.Scanln(&confirmpassword)
if !bytes.Equal([]byte(password), []byte(confirmpassword)) {
fmt.Println("两次输入的密钥不匹配,请重新输入!")
}else {
//处理用户输入的密钥
key := genKey([]byte(password))
//读取文件
info, _ := ioutil.ReadFile(filename)
//对文件加密
dst := Encrypt3(info, key)
// 1.avi 1_encrypted.avi
//获取点的下标
index := strings.LastIndex(filename, ".")
//创建新的文件名称
newfilename := filename[:index] + "_encrypted" + filename[index:]
//写入文件
ioutil.WriteFile(newfilename, dst, 0666)
fmt.Println("已生成加密文件:" + newfilename)
}
}else if command == "解密" {
fmt.Print("请输入文件名称:")
fmt.Scanln(&filename)
var password string
fmt.Print("请输入密钥:")
fmt.Scanln(&password)
key := genKey([]byte(password))
info, _ := ioutil.ReadFile(filename)
src := Decrypt3(info, key)
index := strings.LastIndex(filename, ".")
newfilename := filename[:index] + "_decrypted" + filename[index:]
ioutil.WriteFile(newfilename, src, 0666)
fmt.Println("已生成解密文件:"+newfilename)
}
}