工作中经常涉及和不同编程语言使用3DES加解密的对接问题,很多语言对于同一种加密算法的细节处理还是有些出入的,典型的如加密模式、填充方法。
3DES加解密简介
DES使用分块加密,加密密钥为56位,块大小为64位。由于56位版本的DES加密非常容易破解(一般机器一天以内),就有了和DES兼容性较好的3DES算法。
##原理
3DES加密算法表示为C=EncryptK3(DecryptK2(EncryptK1(message)
,如果K1、K2、K3为密钥,如果各不相同,则相当于加密密钥长度为112(由于中途相遇攻击);解密算法表示为message=DecryptK1((EncryptK2(DecryptK3(C)))
以加密算法举例:
- 使用了3次DES算法,有3个密钥
- 加密时第一个密钥K1用来加密消息(P),输出C1密文
- 第二个密钥K2用来解密C1,输出C2密文
- 第三个密钥K3用来加密C2,输出C3密文
分组密码工作模式
分组密码的工作模式允许使用同一个分组密码密钥对多于一块的数据进行加密,并保证其安全性。分组密码自身只能加密长度等于密码分组长度的单块数据,若要加密变长数据,则数据必须先被划分为一些单独的密码块。通常而言,最后一块数据也需要使用合适填充方式将数据扩展到匹配密码块大小的长度。一种工作模式描述了加密每一数据块的过程,并常常使用基于一个通常称为初始化向量的附加输入值以进行随机化,以保证安全。
对于分组密码工作模式的介绍可参考wiki
常见的工作模式包括ECB,CBC,OFB和CFB等。
分组密码初始化向量(IV)
用于将加密随机化的一个位块,由此即使同样的明文被多次加密也会产生不同的密文,避免了较慢的重新产生密钥的过程。
分组密码填充
块密码只能对确定长度的数据块进行处理,而消息的长度通常是可变的。因此部分模式(即ECB和CBC)需要最后一块在加密前进行填充)。
加密后字节转文本
对消息加密后通常会得到字节数组,在传输时一般会使用BASE64或HEX等进行编码。
多语言举例
统一起见,工作模式选择ECB,填充模式选择PKCS5Padding或使用8-byte块大小的PKCS7Padding(两种填充模式差别可参考StackExchange),使用base64将加密后字节转换为文本密文。
大家在使用时,一定记得要明确工作模式(mode of operation)和填充模式(padding),因为不同语言(甚至同一种语言不同版本)中对于工作模式和填充模式的实现是可以自由选择的。
Java
代码
|
|
注意
注意在使用Cipher.getInstance
选择加密解密算法时,如果选择desede,也即忽略工作模式和填充模式后,将使用默认的”/ECB/PKCS5Padding”。由于其他语言的默认方式可能不同,将导致不同语言在加解密时异常。
使用到生产环境时,需要处理异常
Python
代码
Python2
|
|
Python3
|
|
注意
注意base64的encodestring已不推荐使用,且会在末尾加入”\n”,使用b64encode代替。
python2中cipher.decrypt
和cipher.encrypt
以及base64.b64encode
和base64.b64decode
返回的是str
,而python3中返回的是bytes
。所以python3中unpad时无需再使用ord获取字符的对应ascii数值。
NodeJS
代码
|
|
注意
nodejs中的crypto
依赖openssl,使用>openssl list-cipher-algorithms
获取支持的算法列表。 如果需要选择其他的算法,可参考openssl。
desede其实是3des的别称(反过来说也可以)。
注意使用nodejs时,要使用createDecipheriv
,IV可传入new Buffer(0)
CSharp
代码
|
|
PHP
代码
|
|
CPP
代码
|
|
C++不懂,同事帮忙写的。
以上代码可以在我的Github上找到。
参考:
1 A Security Site
2 使用 PyCrypto 进行 AES/ECB/PKCS#5(7) 加密
3 https://github.com/eXcellme/tripledes-demo
4 PKCS5Padding和PKCS7Padding的区别
5 StackOverflow Difference between DESede and TripleDES for cipher.getInstance()
6 Python2.7 base64 doc , Python3.6 base64 doc
7 GrepCode com.sun.crypto.provider.DESedeCipher OpenJDK8实现
8 YouTube - AES DES 3DES简介
9 YouTube - ECB vs CBC
10 Nodejs crypto api
11 中途相遇攻击Wiki
12 分组密码工作模式Wiki