支付安全
支付安全
信息安全的基础-机密性
明文:加密前的消息叫“明文”(plain text)
密文:加密后的文本叫“密文”(cipher text)
密钥:只有掌握特殊“钥匙”的人,才能对加密的文本进行解密,这里的“钥匙”就叫做“密钥”(key)
“密钥”就是一个字符串,度量单位是“位”(bit),比如密钥长度是 128,指的就是 16 字节的二进制串(一个字节为8位)
- 加密:实现机密性最常用的手段是“加密”(encrypt)
按照密钥的使用方式,加密可以分为两大类:对称加密和非对称加密
解密:使用密钥还原明文的过程叫“解密”(decrypt)
加密算法:加密解密的操作过程就是“加密算法”
所有的加密算法都是公开的,而算法使用的“密钥”则必须保密
密钥
对称加密
指加密和解密时使用的密钥是同一个,是对称的,只要保证了密钥的安全性,那整个通信过程就可以说具有了机密性。 因为通信过程中传输的消息全是用密钥加密后的密文,所以只有拥有密钥的消息发送方和接收方才能解密。 恶意的用户即使能够窃听到我们的消息,看到的也只是加密后的密文,因为没有密钥无法解密出明文,所以就实现了消息发送的机密性,可密钥一旦被窃取,消息就会被破解
AES 加密算法:密钥长度 128、192 或 256,安全强度很高,性能也很好
加密分组模式:先将明文分组,再对每个分组用密钥进行加密,微信支付中使用的对称加密算法就是分组模式中的一种,名为 AEAD_AES_256_GCM
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img.png)
非对称加密
有两个不相同的密钥,一个叫公钥,一个叫私钥,公钥可以公开给任何人使用,而私钥必须严格保密。 使用公钥加密后只能用私钥解密,反过来私钥加密后也只能用公钥解密
非对称加密算法的设计要比对称加密算法复杂很多,因此运算速度比较慢
RSA 加密算法:最著名的非对称加密算法,微信支付中的非对称加密算法使用的就是 RSA
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_1.png)
混合加密
在实际场景中要保证信息传输的安全性,对称加密与非对称加密是相结合使用的,例如先用非对称加密的方式传输对称加密的密钥,这样可以保证密钥被安全的传递,后期信息交换的过程可以使用对称加密进行,这样能保证对称加密的密钥在传输的过程中不会被拦截窃取,又能保证后续在信息传输的过程中加密和解密的效率,HTTPS的底层协议使用的就是这个原理
身份认证
Bob 有一把公钥和私钥,公钥给了三个朋友,私钥自己保留
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_2.png)
Susan 想给 Bob 写信,信件内容需要保密,那么他可以使用 Bob 的公钥将信件内容加密后发送给 Bob,Bob 收到信件后使用私钥解密看到信件内容,只要 Bob 的私钥不泄露这封信就是安全的
如果 Bob 想给 Susan 回信的话,Susan 也需要有自己的公钥私钥,把公钥分发给 Bob。Bob 使用 Susan 的公钥将信件加密后发送给 Susan,Susan 收到信后用自己的私钥解密后进行阅读
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_3.png)
如果把用法反过来的话,使用私钥加密,公钥解密?
Bob 使用自己的私钥加密了一份信件发送给 Susan,可是 Bob 所有的朋友都有他的公钥,因此他们都可以解密 Bob 发送的信件
我们发现私钥加密公钥解密其实并不是为了加密
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_4.png)
Bob 使用自己的私钥对信件原文进行加密,Susan 必须使用 Bob 的公钥才能对信件进行解密,因此 Susan 能够确认的是这封信确实是 Bob 发出的,因为 Susan 使用的是 Bob 的公钥对信件进行解密,那么加密方一定是使用了 Bob 的私钥对信件进行加密。因此私钥加密公钥解密其实并不是为了加密,而是身份认证
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_5.png)
- 公钥加密,私钥解密的作用是加密信息
- 私钥加密,公钥解密的作用是身份认证
摘要算法
摘要算法就是我们常说的散列函数、哈希函数(Hash Function),它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”
假设一个任意长度字符串数据 Z 经过哈希运算之后会得到固定长度字符串数据 H ,那么我们说 H 就是 Z 的哈希结果又称作数据指纹或者是摘要。MD5就是一个非常典型的摘要算法
摘要算法特点:
- 不可逆:单向的加密算法,只有算法,没有密钥,加密后的数据是没有办法解密的,不能从摘要逆推出原文
- 难题友好性:想要破解只能采用暴力枚举
- 发散性:只要对原文进行一点点的改动,宅哟啊就会发生剧烈变化(雪崩效应)
- 抗碰撞性:原文不同,计算后的摘要也要不同
常见摘要算法:MD5、SHA1、SHA2(SHA224、SHA256、SHA384)
MD5和SHA1被证明不具有强的抗碰撞性,目前用的比较多的是SHA2(一系列算法的统称,SHA224、SHA256、SHA384对应可以生成28个字节,32个字节,48个字节的摘要)
数字签名
Bob决定给Pat写一封信,信件的内容不需要加密,但是要保证Pat收到信之后能够确认这封信是没有被篡改过的
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_6.png)
Bob先用摘要算法生成信件原文的摘要(MessageDigest),接着将摘要附在信件原文的下面一起发送给Pat,Pat收到信件后使用和Bob一样的摘要算法加密信件的原文得到信件的摘要,接着将加密后的摘要和Bob在原文中附加的摘要做一下对比,如果一致说明信件没有被篡改过
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_8.png)
这种方式看似好像解决了我们数据完整性的问题,但还是有一个致命的漏洞,如果信件被黑客截获,假如信件内容是明文传输,且黑客知晓是哪种摘要算法后修改了原文并根据原文使用对应的摘要算法生成了新的摘要附加在原文下面伪装成Bob将信件发送给Pat,这样Pat就收到黑客的信件还误以为是Bob给他发送的信件,所以说摘要算法不具有机密性,因此一定要加入密钥来确保信息的机密性
正确步骤:
Bob写完信件之后先用摘要算法生成信件的摘要,接着使用自己的私钥将摘要加密,加密后的结果我们称之为数字签名,将数字签名附在信的原文下面一起发给Pat
Pat收到信件之后取下数字签名,使用Bob的公钥解密得到信件的摘要,接着使用和Bob一样的摘要算法加密信件的原文得到信件的摘要与用公钥解密后得到的摘要进行比对,如果一致说明信件就是Bob发的,且没有经过篡改的,这个过程我们称之为验签(验证数字签名)
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_9.png)
我们发现,即使黑客修改了信件的原文内容,即使黑客能够通过摘要算法生成新的摘要,但是因为他没有Bob的私钥,因此无法对摘要进行加密,无法生成只有Bob才能生成的数字签名,所以这个信也就无法被篡改了,微信支付中的签名和验签的过程就是这个原理
数字签名通常定义了两种运算:签名和验签。发送者用自己的私钥对消息生成的摘要进行签名,接收者用对方的公钥进行验签。因此,在使用数字签名时,需要通信的双方都要事先生成公钥、私钥,并且完成双方的公钥交换。其中私钥是只能由拥有者使用的不公开密钥,公钥是可以公开的密钥
数字证书
CA架构是一种基于公钥技术的安全架构,它使用数字证书来验证用户和服务器之间的身份和信任关系
数字证书是一种包含了公钥、持有者信息、有效期等内容的电子文件,它由一个权威机构(CA)签发和管理
CA是一个负责颁发、管理、撤销数字证书的机构,它可以是一个独立的第三方机构,也可以是系统内部的一个组件
在 CA 架构中,用户和服务器之间的通信流程如下:
- 用户向CA申请数字证书,提供自己的公钥和身份信息
- CA 验证用户的身份信息,如果通过,则给用户颁发一个包含了用户公钥和其他信息的数字证书,并用自己的私钥签名
- 用户用自己的私钥对要发送给服务器的数据进行加密,并附上自己的数字证书
- 服务器收到用户发送的数据后,用CA提供的公钥验证用户数字证书的有效性,如果通过,则用用户公钥解密数据,并用自己的私钥对要回复给用户的数据进行加密,并附上自己的数字证书
- 用户收到服务器回复的数据后,用CA提供的公钥验证服务器数字证书的有效性,如果通过,则用服务器公钥解密数据
这样就实现了双向认证和加密通信
Doug想欺骗Pat,他把自己的公钥发送给Pat并谎称这是Bob的公钥。此时Pat拥有的实际上是Doug的公钥,因此Doug可以冒充Bob用自己的私钥做成数字签名写信给Pat,Pat用Doug的公钥进行验签,验签是可以通过的,Pat误以为是在和Bob通信,但其实对方是Doug
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_10.png)
解决该问题的办法就是使用数字证书
数字证书里的一些重要信息:
- 公钥:申请者的公钥(为了防止申请者的公钥被伪造,公钥不会采用直接公开发布的形式,而是会被放在数字证书中)
- 所有者:证书的申请者
- 颁发者:CA(Certificate Authority)第三方证书认证机构
- 有效期:证书的使用期限
- 签名哈希算法:指定摘要算法,用来计算证书的摘要
- 指纹:证书的摘要,保证证书的完整性
- 签名算法:用于生成签名,确保证书是由CA签发
- 序列号:证书的唯一标识
由于公钥本身并不含有拥有者的身份信息,使用时无法确认它是真实有效的。所以需要证书认证机构(简称 CA)在核实公钥拥有者的信息后,将公钥拥有者的身份信息(如商户号、公司名称等),公钥、签发者信息、有效期以及扩展信息等进行签名,制作成“证书”
CA颁发数字证书的流程:CA使用证书信息中指定的哈希算法生成摘要(证书的指纹),然后CA根据证书中的签名算法用CA的私钥对摘要进行加密生成证书签名,最后把签名和证书的基本信息一起发布,这样Bob就得到了一个数字证书
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_7.png)
Bob拿到数字证书后就可以放心的给Pat发送信件了,只要在签名的同时附上数字证书即可
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_11.png)
Pat收到信件后,首先把数字证书从信件中取出来,对数字证书当中的数字签名进行验签:
- Pat使用证书信息当中指定的哈希算法根据证书信息计算出证书的摘要
- 使用CA的公钥从数字证书的签名中解密出数字证书的摘要
- 将两个摘要进行比较,如果两个摘要相同则说明验签是通过的,数字证书验签通过了
此时Pat则可以从数字证书中获取到Bob的公钥,在数字证书中定义了证书的所有者,这样Doug就无法去伪造数字证书了,因为他向CA申请数字证书时必须提供真实身份,CA也会对这个身份进行核实,因此Pat现在拿到了Bob真实的公钥
此时需要用Bob的公钥对信件的数字签名进行验证,需要先用相同的哈希算法计算出信件的摘要,然后用刚刚从数字证书中获取到的Bob公钥对信件的签名进行解密,得到信件加密后的摘要,将两个摘要进行比对,如果一致则验签通过,最终确定和Pat通信的一定是Bob且信件内容也没有被篡改
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_13.png)
数字证书应用场景-HTTP协议
HTTP协议主要用于网页加密,首先一个网站需要使用HTTPS协议,因此网站需要向CA申请数字证书,CA用自己的私钥对数字证书的基本信息进行了加密并进行了签名
有了数字证书和一些必要的条件之后,网站就可以以HTTPS协议的形式发布在互联网上了
当客户端浏览器向网站发出了另一个加密请求,网站对网页进行加密之后会连同它的数字证书一起发送给这个客户端的浏览器。客户端的浏览器接收到服务器发送过来的数字证书后会使用CA的公钥去解密这个数字证书并对数字证书进行验签,CA的公钥就是证书认证机构的公钥,默认情况下我们的操作系统当中都会有权威的CA证书列表,CA证书列表就会存放CA的公钥
与此同时客户端也会判断当前访问的网址和数字证书信息中证书持有者是否一致,如果不一致说明这个网站是伪装的,如果数字证书过期/数字证书被吊销/颁发数字证书的CA机构不是特别正规,浏览器都会发出一些网站不安全的警告信息,如果数字证书是可靠的,客户端就可以顺利从证书中获取到网站的公钥了,接下来客户端就可以使用网站的公钥对信息进行加密后与网站进行通信了
![](https://img.sherry4869.com/blog/it/java/intermediate/pay/weixin/payment-security/img_12.png)