5. 支付里面的常用加密
谣言
在我面试的人员里面,很多人无法分清楚,加密和校验的概念。会有不少人认为MD5是一种加密方式。这里需要大家区分好这2种概念:
概念 | 应用场景 | |
加密 | 数据可以被还原,常见的对称加密,非对称加密,下面的内容会详细介绍 | 数据安全传输 |
校验 | 数据不能被还原,常见的有MD5,SHAx,CRC,LRC | 数据在接收到后,对数据的完整性进行校验,防止中间产生数据丢失或者篡改 |
加密类型:
- 对称加密:DES,AES
- 非对称加密:RSA,ECC
对称加密的概念
用一个加密和解密的Key是相同的。属于可逆运算
非对称加密
加密和解密是不同的Key,属于不可逆运算,一般叫做公钥和私钥。
公钥一般用来加密,私钥用来解密。私钥用来签名,私钥用来验签。
常规问题:是否可以用私钥加密,公钥解密,公钥签名,私钥验签?
先告诉大家,答案是可以的。
签名 = 原始数据计算Hash + 用私钥对Hash进行RSA加密
所以,本质上来说,签名,其实就是用私钥加密,反过来当然也是成立的,只是说,这种场景一般不会遇到。
优缺点:
优点 | 缺点 | |
对称加密 | 速度快 | 在工作之前,需要2边协商好秘钥,并且双边保管秘钥存在很大的安全隐患 |
非对称加密 | 可以以公钥的方式外发 | 速度慢,效率低 |
结合上面的优缺点,如果数据全部使用非对称加密的话,那基本我们的设备会把所有计算资源浪费在加密上面,所以,把2者结合起来是一个非常好的做法,这也是目前的大部分加密应用场景。我们常用的SSL(Https = http + SSL),PGP文件加密这些都是应用场景。
以上为常规银行远程下发传输秘钥的流程图,和SSL原理一样,但是SSL还有多了公钥签名认证过程,和加密方式选择过程,更加复杂一些,有兴趣的小伙伴可以去参考一下。SSL原理
这里值得提一下,SSL的单双向认证需要注意点
目的 | 应用场景 | |
SSL单向认证 | 客户端认证服务端,防止DNS劫持导致连接到非法服务器 | App/网页 和服务器交互,是我们最常见的一种方式 |
SSL双向认证 | 2边相互认证 | 服务器和服务器之间交互,一般在安全要求性比较高的场景 |
App/网页一般不会使用双向认证(有些场景需要单独网页安装安全证书),因为双向认证有2份证书:客户端的公私钥,服务端公私钥。由于App一般是公开的,也就非常容易拿到客户端的公私钥,拿到了,那双向认证也就完全失去了意义。
在做App时,一般我们使用时,会有操作系统内部内置的证书进行证书认证,这里建议,最好不要使用系统默认的,而在应用程序里面单独做一次验证,在某些企业环境下,会有证书劫持的情况存在,支付数据如果明文暴露出来那是非常严重的问题。
DES
这种加密方式,可能会被无数人吐槽,甚至在代码检测时,就直接报错,使用了过时不安全的加密方式。但是,事实却是,这是支付里面最最主流的加密方式,为何?因为银行系统,所有人都知道,是老古板的东西,几十年没什么大变化
当然,为了加强一些DES的加密强度,出现了TDES(也有人加3DS),CBC……一些附件措施,其实都是由最原始的DES各种变换组合而来。
3DES 比 DES,多了2次DES加密,所有加密强度是DES的3倍,做支付的小伙伴,必须得知道一些基础原理,因为有时你和银行对接时,出了问题,你得有足够的信心证明自己是对的。不然这群老大爷是不会理你的。
普通DES的秘钥长度是8字节,3DES最常见的是16字节,也有时会出现24字节,但是都是8的倍数。
以下是3DES如何有DES组成的伪代码。
/*
原始数据SrcData(长度必须是8字节)
秘钥数据Key(长度必须是8/16/24字节)
*/
// step 1 将KEY按照8字节进行拆分
Key --> Key1(8 bytes) + Key2(8 bytes) + Key3(8 bytes) // 这里需要注意的是Key3,如果Key的长度是16字节,那Key3 = Key1, 如果是24字节,那就是最后8字节
// step 2 用Key1对原始数据进行加密
EnData1 = DES(SrcData, Key1)
// step 3 用Key2对上个结果进行解密
EnData2 = RDES(EnData1, Key2)
// step 4 用Key3对上个结果进行加密
EnData3 = DES(EnData2, Key3)
// EnData3 就是得到的结果,解密的话就刚好反着来一遍
问题一:需要加密的数据长度一般不是8字节。
解决问题:对原始数据拆分成多个8字节,不够就补齐成8字节,进行多次加密。
问题二:补齐后的数据,加密完,进行解密时,没办法还原,不知道哪些是原始数据,哪些是补的数据
解决问题:这里就延伸出来补数据的概念:最常见的是PKCS5Padding。
/*
PKCS5Padding 原理就是,如果长度不满足8的倍数,那计算出,还差多少字节到8的倍数,然后用这个数据进行填充
*/
假设原始数据是SrcData = 01 02 03 --> 01 02 03 05 05 05 05 05
// step 1 计算余数
PaddingLen = 8 - Len(SrcData)%8
// step 2 填充
SrcData + PadingLen 个 PendingLen
// 这样,我们解密数据后,也是反向进行删除padding数据进行数据还原
所以,一般如果是NoPadding模式,原始数据必须是8的倍数,如果是PKCS5Padding模式,那就不需要保证原始数据是8的倍数了,这也是很多小伙伴会遇到的问题,经常自己也搞不清楚为什么有时代码会出异常。
问题三:如果数据存在8个字节相同的情况,那加密出来的结果,也会有8个字节相同的问题,这让**难度变得很低
解决问题:采用CBC模式。主要核心思想就是,用前面8字节数据加密结果,和后面8字节进行异或,异或后的结果再用来加密作为后8字节加密的结果输出,以此类推无限循环。并且需要一个初始化限量IV,IV的功能就是第一个8字节进行异或的。所以,CBC相对于默认的ECB来说,多了一个IV参数。实现方式稍微长一点点,这里不再赘述。可以自行搜索。
下一篇幅,会对实际银行卡使用DES的场景进行描述,ISO8583里面的DES
其实这里还有问题产生,我留给各位看官自己想想:
1. CBC这种后面的计算依赖前面的计算,对于现在的多核CUP来说,显然是不能发挥并行计算的优势,对于比较大的文件加密,会有效率问题产生。
2. 加密结果没有校验值,中间如果被人篡改了,解密后,也无法被发现
AES
相信稍微有点点加密知识的人都懂这东西了,这是目前来说,最最最常用的一种对称加密。加密强度比DES高很多。这里我不再赘述,可以自行搜索。百科
RSA
借用一下别人的成果,没必要再造*:百科
ECC
新型的非对称加密算法,用更短的秘钥,做加密强度更高的加密,国内的国密算法也是ECC改编过来的。科普
推荐阅读