Go语言的DES加密(CBC模式, ECB模式)
2017-09-22 00:00
260 查看
摘要: DES加密分几种模式: ECB, CBC, CFB, OFB
本文主要说一下ECB和CBC, 想要不同语言之间加密解密互通, 只要保证加密模式, 向量一致即可, 并没有那么复杂
go的DES的默认隐藏了ECB模式, 因为go认为ECB不安全, 所以不建议使用,就隐藏了,
然而接口却需要采用ECB模式(吐槽写文档的人, 并没有写明使用了ECB模式,
这让我耗费了大量的时间来猜测他的加密模式)
ECB(电子密本方式)就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
特点
简单,有利于并行计算,误差不会被传送;
不能隐藏明文的模式;在密文中出现明文消息的重复
可能对明文进行主动攻击;加密消息块相互独立成为被攻击的弱点
CBC(密文分组链接方式)有向量的概念, 它的实现机制使加密的各段数据之间有了联系。
加密步骤:
首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
之后的数据以此类推,得到Cn
按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程:
首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
之后依此类推,得到Dn
按顺序连为D1D2D3......Dn即为解密结果。
特点
不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
每个密文块依赖于所有的信息明文消息中一个改变会影响所有密文块
发送方和接收方都需要知道初始化向量
加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化。
本文主要说一下ECB和CBC, 想要不同语言之间加密解密互通, 只要保证加密模式, 向量一致即可, 并没有那么复杂
Go语言的DES加密(CBC模式, ECB模式) ---- 与java加密互通
问题场景:
业务需要对接接口, 采用DES加密方式加密, 于是google一下go的DES加密方式,go的DES的默认隐藏了ECB模式, 因为go认为ECB不安全, 所以不建议使用,就隐藏了,
然而接口却需要采用ECB模式(吐槽写文档的人, 并没有写明使用了ECB模式,
这让我耗费了大量的时间来猜测他的加密模式)
ECB
概念ECB(电子密本方式)就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
特点
简单,有利于并行计算,误差不会被传送;
不能隐藏明文的模式;在密文中出现明文消息的重复
可能对明文进行主动攻击;加密消息块相互独立成为被攻击的弱点
CBC
概念CBC(密文分组链接方式)有向量的概念, 它的实现机制使加密的各段数据之间有了联系。
加密步骤:
首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
之后的数据以此类推,得到Cn
按顺序连为C1C2C3......Cn即为加密结果。
解密是加密的逆过程:
首先将数据按照8个字节一组进行分组得到C1C2C3......Cn
将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)
将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2
之后依此类推,得到Dn
按顺序连为D1D2D3......Dn即为解密结果。
特点
不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
每个密文块依赖于所有的信息明文消息中一个改变会影响所有密文块
发送方和接收方都需要知道初始化向量
加密过程是串行的,无法被并行化(在解密时,从两个邻接的密文块中即可得到一个平文块。因此,解密过程可以被并行化。
代码
//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)] }
相关文章推荐
- Android DES加密的CBC模式加密解密和ECB模式加密解密
- Android DES加密的CBC模式加密解密和ECB模式加密解密
- <加密算法c#>——— 3DES加密之ECB模式 和 CBC模式
- go语言实现设计模式(一):策略模式
- 设计模式-策略模式(Go语言描写叙述)
- python 实现DES加密 ECB模式
- go语言: 设计模式-代理模式(Go语言描述)
- 设计模式-适配器模式(Go语言描写叙述)
- Go语言中Restful模式与Routes路由框架
- go语言】Goroutines 并发模式
- Go语言备忘录(3):net/http包的使用模式和源码解析
- Go语言设计模式实践:迭代器(Iterator)
- Go 语言net/http 包使用模式:监听多端口等等
- 【go语言】Goroutines 并发模式(一)
- Android DES加密的CBC和ECB加密解密模式
- go语言快速入门:简单工厂模式的实现(23)
- 超赞的GO语言设计模式和成例集锦
- Java版适用于PHP版3DES加密解密(PHP语言开发的MCRYPT_3DES算法、MCRYPT_MODE_ECB模式、PKCS7填充方式)
- go语言并发编程-----Goroutines 并发模式
- Go语言设计模式实践:组合(Composite)