博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言加密算法之DES(CBC模式, ECB模式)
阅读量:7092 次
发布时间:2019-06-28

本文共 3249 字,大约阅读时间需要 10 分钟。

hot3.png

Go语言的DES加密(CBC模式, ECB模式) ---- 与java加密互通

问题场景:

业务需要对接接口, 采用DES加密方式加密, 于是google一下go的DES加密方式,

go的DES的默认隐藏了ECB模式, 因为go认为ECB不安全, 所以不建议使用,就隐藏了,
然而接口却需要采用ECB模式(吐槽写文档的人, 并没有写明使用了ECB模式,
这让我耗费了大量的时间来猜测他的加密模式)

ECB

  • 概念
    ECB(电子密本方式)就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
  • 特点
  1. 简单,有利于并行计算,误差不会被传送;
  2. 不能隐藏明文的模式;在密文中出现明文消息的重复
  3. 可能对明文进行主动攻击;加密消息块相互独立成为被攻击的弱点

CBC

  • 概念
    CBC(密文分组链接方式)有向量的概念, 它的实现机制使加密的各段数据之间有了联系。
  • 加密步骤:
  1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
  2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
  3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
  4. 之后的数据以此类推,得到Cn
  5. 按顺序连为C1C2C3......Cn即为加密结果。
  • 解密是加密的逆过程:
  1. 首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
  2. 将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
  3. 将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
  4. 之后依此类推,得到Dn
  5. 按顺序连为D1D2D3......Dn即为解密结果。
  • 特点
  1. 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
    每个密文块依赖于所有的信息明文消息中一个改变会影响所有密文块
  2. 发送方和接收方都需要知道初始化向量
  3. 加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化。

代码

//ECB加密func EncryptDES_ECB(src, key string) string {    data := []byte(src)    keyByte := []byte(key)    block, err := des.NewCipher(keyByte)    if err != nil {        panic(err)        }    bs := block.BlockSize()    //对明文数据进行补码    data = PKCS5Padding(data, bs)    if len(data)%bs != 0 {        panic("Need a multiple of the blocksize")    }    out := make([]byte, len(data))    dst := out    for len(data) > 0 {        //对明文按照blocksize进行分块加密        //必要时可以使用go关键字进行并行加密        block.Encrypt(dst, data[:bs])        data = data[bs:]        dst = dst[bs:]    }    return fmt.Sprintf("%X", out)}//ECB解密func DecryptDES_ECB(src, key string) string {	data, err := hex.DecodeString(src)	if err != nil {		panic(err)	}	keyByte := []byte(key)	block, err := des.NewCipher(keyByte)	if err != nil {		panic(err)	}	bs := block.BlockSize()	if len(data)%bs != 0 {		panic("crypto/cipher: input not full blocks")	}	out := make([]byte, len(data))	dst := out	for len(data) > 0 {		block.Decrypt(dst, data[:bs])		data = data[bs:]		dst = dst[bs:]	}	out = PKCS5UnPadding(out)	return string(out)}//CBC加密func EncryptDES_CBC(src, key string) string {	data := []byte(src)	keyByte := []byte(key)	block, err := des.NewCipher(keyByte )	if err != nil {		panic(err)	}	data = PKCS5Padding(data , block.BlockSize())	//获取CBC加密模式	iv := keyByte //用密钥作为向量(不建议这样使用)	mode := cipher.NewCBCEncrypter(block, iv)	out := make([]byte, len(data))	mode .CryptBlocks(out, data)	return fmt.Sprintf("%X", out)}//CBC解密func DecryptDES_CBC(src, key string) string {	keyByte := []byte(key)	data, err := hex.DecodeString(src)	if err != nil {		panic(err)	}	block, err := des.NewCipher(keyByte)	if err != nil {		panic(err)	}	iv := keyByte //用密钥作为向量(不建议这样使用)	mode := cipher.NewCBCDecrypter(block, iv)	plaintext := make([]byte, len(data))	mode.CryptBlocks(plaintext, data)	plaintext = PKCS5UnPadding(plaintext)	return string(plaintext)}//明文补码算法func PKCS5Padding(ciphertext []byte, blockSize int) []byte {	padding := blockSize - len(ciphertext)%blockSize	padtext := bytes.Repeat([]byte{byte(padding)}, padding)	return append(ciphertext, padtext...)}//明文减码算法func PKCS5UnPadding(origData []byte) []byte {	length := len(origData)	unpadding := int(origData[length-1])	return origData[:(length - unpadding)]}

转载于:https://my.oschina.net/imhuayi/blog/1541840

你可能感兴趣的文章
诚聘Java高级开发工程师
查看>>
linux 下查看登陆用户
查看>>
趁热来一发——关于避免死锁时测试结果颠覆三观不得不思考虫生这件小事
查看>>
我的友情链接
查看>>
人脉通分享工能,点击分享到微信或者qq的分享链接打开H5,提示用户用浏览器打开,点击下载,有有app...
查看>>
Java:String和Date、Timestamp之间的转换
查看>>
Mongodb概述
查看>>
yii 安全措施 (Security)
查看>>
性能监测与优化命令top
查看>>
apache
查看>>
Logback学习笔记1
查看>>
随笔一篇
查看>>
小波说雨燕 第三季 构建 swift UI 之 UI组件集-视图集(三)Activity Indicators视图 学习笔记...
查看>>
浅谈物联网所面对的问题和挑衅
查看>>
期刊发表要求都有哪些
查看>>
php导出数据到excel,身份证等数字常用格式
查看>>
我的友情链接
查看>>
Grub 配置解析(1)
查看>>
Oracle数据库管理常用的监控脚本------极大的简化运维工作
查看>>
Oracle10g之SGA与PGA分配建议
查看>>