SSL
SSL为安全套接层协议,是用于在Web浏览器和Web服务器之间进行安全信息交换的一种协议。其主要提供了两个核心的安全服务:数据加密和身份验证。作为网络安全的基础协议,SSL在网络数据传输中起到了至关重要的保密和安全保障作用。
优点
- 保密性:在握手过程中,客户端和服务器会协商出一个共同的密钥和加密算法,这个密钥随后会被用于在后续的数据传输中进行加密和解密。同时,SSL也支持对称密钥加密,进一步增强了数据的安全性。
- 完整性:通过在传输的信息中嵌入一个信息鉴别码(MAC),确保数据在传输过程中没有被篡改或损坏。这种机制确保了数据的完整性和真实性。
- 可以双向认证:这意味着客户端和服务器都需要验证对方的身份。这个过程通过SSL证书和密钥来完成,进一步增强了通信的安全性。
单向认证
双向认证
公钥与私钥
在SSL的单向或双向认证过程中,公钥和私钥扮演着核心角色,它们分别用于加密和解密数据。因此,了解公钥和私钥的定义和作用至关重要。
公钥(Public Key)和私钥(Private Key)是一对通过特定加密算法生成的密钥。这种加密方式被称为非对称加密,主要应用于保证数据传输的安全性。公钥用于数据加密,而私钥则负责数据解密。这就确保了只有持有相应私钥的接收者才能成功解密用公钥加密的数据,从而保证了数据传输的安全性。
公钥是公开可用的密钥部分,而私钥则是保密的、非公开的部分。服务端或客户端持有各自的私钥,并妥善保管,以防止未授权的访问和数据泄露。在加密和解密过程中,如果使用不匹配的公钥和私钥进行操作,将无法成功解密数据,从而增强了数据的安全性。
对称加密VS非对称加密
我们刚刚提到公钥与私钥是用于非对称加密算法,那么我们就来了解一下对称算法和非对称算法的区别。
- 对称加密算法
对称加密算法,也称为私钥加密算法,是指加密和解密使用同一个密钥的加密方式。在通信过程中,双方必须共享这个密钥,使得发送方可以用该密钥加密数据,接收方则用同样的密钥进行解密。
- 非对称加密算法
相比之下,非对称加密算法,也称为公钥加密算法,采用了两个密钥:公钥和私钥。公钥用于加密数据,而私钥用于解密数据。公钥是公开的,任何持有公钥的人都可以加密数据,而只有私钥的持有者才能解密数据。
SSL证书
SSL证书就是遵守SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发的证书,具有服务器身份验证和数据传输加密功能。证书中包含了一些关键信息,如网站所有者、证书颁发机构、证书有效期和公钥等。
证书格式转换
openssl x509 -in certificate.crt -outform der -out certificate.cer
提取公钥
openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
SSL pinning
概要
SSL Pinning是一种重要的安全措施,主要用于验证移动应用程序与服务器之间的SSL连接是否合法。通过将服务器提供的SSL证书或公钥预先内置到移动应用程序中,SSL Pinning能够确保应用程序仅能与预期的服务器建立安全连接,从而有效防止中间人攻击者对连接的拦截和篡改。
SSL Pinning主要包含两种方式:Certificate Pinning(证书锁定)和Public Key Pinning(公钥锁定)。证书锁定主要是将服务器提供的SSL/TLS证书内置到移动应用程序中,通过比对服务器端证书的内容来确定连接的合法性;而公钥锁定则是从服务器证书中提取公钥并将其内置到移动应用程序中,通过与服务器端公钥的比对来验证连接的合法性。
证书锁定VS公钥锁定
证书锁定
证书锁定适用于所有类型的证书,包括了自签名证书和CA颁发的证书。但因为证书都有有效期问题,当证书有效期到期后我们需要更换移动应用程序中的证书,以确保证书永远处于有效期内。
公钥锁定
对于到期的SSL证书,续签时可以保证公钥始终不变。所以对于证书有效期短、需要频繁更换证书的情况,使用公钥锁定可以避免替换移动应用程序内的证书而需要发版的复杂流程。
SSL pininng实现方式
综合考虑后项目中使用了公钥锁定来完成APP中的SSL pinning,最后决定使用react-native-ssl-pinning完成该功能。
使用方式参考:https://github.com/MaxToyberman/react-native-ssl-pinning
环境
- React Native
- Nom
引入依赖
npm install react-native-ssl-pinning --save
添加SSL证书/公钥
IOS
直接将.cer证书文件添加至Xcode,并在archive出IOS APP安装包时将其打包进去。
Andriod
- 提取SSL证书的公钥
openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
- 调用接口时携带公钥信息
fetch("https://XXXXX", {
method: "GET" ,
pkPinning: true,
sslPinning: {
certs: ["sha256/公钥信息"]
}
})
工作原理
react-native-ssl-pinning
库采用了公钥锁定机制,将服务器公钥嵌入到APP中。这意味着,当APP尝试与服务器进行通信时,如果检测到的公钥与预置的不匹配,连接将被立即断开。
对于iOS版本的APP来说,这个库从包含在应用中的cer证书文件中提取公钥。尽管实现过程看似是证书锁定,但实际上,它仅使用证书中的公钥进行验证。更为巧妙的是,如果证书过期,而服务器续签了具有相同公钥的新证书,客户端无需进行任何修改。这意味着,即使证书过期,只要公钥保持一致,客户端与服务器的连接仍然是安全且有效的。
对于Android版本的APP来说,SSL公钥信息被存储在APP中。当应用发起网络请求时,该库会使用公钥锁定方式来验证连接的安全性。这种方法确保了应用只能与预期的、受信任的服务器建立连接,大大降低了中间人攻击的风险。
总的来说,react-native-ssl-pinning
库通过公钥锁定提供了一种灵活且安全的解决方案,无论是iOS还是Android平台的应用都能从中受益。这不仅提高了应用的整体安全性,也增加了用户对应用的信任度。
留言