Go语言与3重DES加密算法 —— 3DES加密算法概念、实现原理、实例

 

3DES

三重DES是为了增强DES的强度,将DES重复3次所得到的一种密码算法

3DES加密机制:

 

说明:

  1. 明文经过三次DES处理才变成最后的密文,由于DES密钥的长度实质上是56比特,因此三重DES的密钥长度就是56*3=168比特。
  2. 三重DES并不是进行三次加密(加密->加密->加密),而是加密->解密->加密的过程,这种设计是为了让3des能够兼容普通的des,当三重des密钥全部相同时,3重des就xi相当与普通的des,这是因为在前两轮加密->解密之后,得到的就是最初的明文,因此以前的des加密的密文,也就可以通过这种方式用三重des来进行解密。

三重DES解密机制:

1.简单明文处理 

  1. 首先定义一个加密函数,实现将明文通过24个字节数的key进行加密得到一个密文
  2. 通过key并利用
    des.NewTripleDESCipher(key)
    得到一个block接口
  3. 将明文进行填充处理,获得其长度是block.size()的倍数,这样才可以进行密文组明文组加密处理
  4. 通过
    iv := key[:block.BlockSize()]
    //创建CBC加密模式
    blockMode := cipher.NewCBCEncrypter(block, iv)
    dst := make([]byte, len(src))
    //加密
    blockMode.CryptBlocks(dst, src)
  5. 将其dst返回

 

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

 

2.将文件进行3重DES加密

读取文件,将文件内容以[]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)
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
3DES(或称为Triple DES)是三数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。 最早的定义了该算法的标准(ANS X9.52,1998年发布)将其描述为“三数据加密算法(TDEA)”— 即为ANSI X3.92中定义的数据加密算法(DEA)的三次复操作— 而完全没有使用术语“3DES”或“DES”。FIPS PUB 46-3(1999)定义了“三数据加密算法”(TDEA),也使用了术语“Triple DES”和“DES”。该标准中互换的使用“数据加密算法”(DEA)和“DES”的概念,其中以此开始DES的定义: 数据加密标准(DES)应当包括下文中的数据加密算法DES[4])与三数据加密算法(TDEA,如ANSI X9.52中所描述的) NIST SP 800-67(2004,2008[5])主要使用术语TDEA,但也提到了“Triple DES(TDEA)”。ISO/IEC 18033-3(2005)使用“TDEA”,但其中提到: TDEA通称Triple DES(数据加密标准)。 没有一个定义了本算法的标准使用术语“3DES”。 3DESughhhg34465345556555678==算法== 3DES使用“密钥包”,其包含3个DES密钥,K1,K2和K3,均为56(除去奇偶校验)。加密算法为: 密文 = EK3(DK2(EK1(平文))) 也就是说,使用K1为密钥进行DES加密,再用K2为密钥进行DES“解密”,最后以K3进行DES加密。 而解密则为其反过程: 平文 = DK1(EK2(DK3(密文))) 即以K3解密,以K2“加密”,最后以K1解密。 每次加密操作都只处理64数据,称为一块。 无论是加密还是解密,中间一步都是前后两步的逆。这种做法提高了使用密钥选项2时的算法强度,并在使用密钥选项3时与DES兼容。 密钥选项[编辑] 标准定义了三种密钥选项: 密钥选项1:三个密钥是独立的。 密钥选项2:K1和K2是独立的,而K3=K1 密钥选项3:三个密钥均相等,即K1=K2=K3 密钥选项1的强度最高,拥有3 x 56 = 168个独立的密钥。 密钥选项2的安全性稍低,拥有2 x 56 = 112个独立的密钥。该选项比简单的应用DES两次的强度较高,即使用K1和K2,因为它可以防御中途相遇攻击。 密钥选项3等同与DES,只有56个密钥。这个选项提供了与DES的兼容性,因为第1和第2次DES操作相互抵消了。该选项不再为国家标准科技协会(NIST)所建议[6],亦不为ISO/IEC 18033-3所支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值