ssl pining
Welcome to this serie of articles about Android Security and how you can improve tremendously the protection of your users, by implementing 3 things that provide a great effort/safety ratio.
欢迎阅读有关Android安全性的文章系列,以及如何通过实现3个提供极大努力/安全性比率的方法来极大地改善对用户的保护。
Today we are going to look at protecting the HTTPS connection. Your APIs, your user data use that link and it is crucial that the data is encrypted and not readable during the transfer, moreover that the server the App is communicating with is the one intended.
今天,我们将研究保护HTTPS连接。 您的API,您的用户数据使用该链接,并且在传输过程中对数据进行加密且不可读是至关重要的,此外,与应用程序通信的服务器是预期的服务器。
先决条件 (Prerequisite)
An HTTPS connection to your API, and if you do not use HTTPS yet, then start immediately.
与您的API的HTTPS连接,如果尚未使用HTTPS,请立即启动 。
You will need OkHTTP (or Retrofit), that is providing a method to setup SSL Pinning with just a couple of line of code.
您将需要OkHTTP (或Retrofit),它提供了一种仅用几行代码即可设置SSL Pinning的方法。
A browser or access to the HTTPS certificate.
浏览器或对HTTPS证书的访问。
OpenSSL
的OpenSSL
查找PIN码 (Finding the PIN)
HTTPS certificates are coming with a a Fingerprint, this is a hash (SHA1, SHA256) of the actual certificate. and we are going to use it to verify the authenticity of the server we are connecting to.
HTTPS证书附带一个指纹,这是实际证书的哈希(SHA1,SHA256)。 我们将使用它来验证所连接服务器的真实性。
With a Browser, connect to your HTTPS domain. Click on the padlock icon to show the Certificate details.
使用浏览器,连接到您的HTTPS域。 单击挂锁图标以显示证书详细信息。
![Image for post](https://miro.medium.com/max/9999/1*HLmGfCfKowUorpa1OZzlpQ.png)
On the screenshot above, with Safari, we can see at the bottom the Fingerprints.
在上面的屏幕快照中,使用Safari,我们可以在底部看到“指纹”。
I do recommend you to use SHA-256 for your SSL Pinning as it is more secure than SHA1.
我确实建议您使用SHA-256进行SSL固定,因为它比SHA1更安全。
Keep the SHA-256 somewhere in your editor.
将SHA-256放在编辑器中的某个位置。
you can also use openssl command line to get the SHA-256
您还可以使用openssl命令行获取SHA-256
SHA256:openssl x509 -noout -fingerprint -sha256 -inform pem -in cert.pem
SHA256: openssl x509 -noout -fingerprint -sha256 -inform pem -in cert.pem
SHA256 with Base64 encode: openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dust -sha256 -binary | openssl enc -base64
使用Base64编码的SHA256: openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dust -sha256 -binary | openssl enc -base64
openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dust -sha256 -binary | openssl enc -base64
使用指纹来验证证书 (Using the Fingerprint to verify the certificate)
The idea of SSL Pinning is to checksum the SSL certificate that we are going to connect to and apply a Hash algorithm, in this instance SHA256.
SSL固定的想法是对我们将要连接的SSL证书进行校验和并应用哈希算法,在本例中为SHA256。
OkHTTP is going to apply the same SHA256 checksum algorithm on the certificate it is connecting to, and compare it with the provided and trusted SHA256 checksum found earlier.
OkHTTP将对要连接的证书应用相同的SHA256校验和算法,并将其与之前提供的受信任的SHA256校验和进行比较。
If the checksums match, it means the certificate OkHTTP is connected to, is genuine and therefore we can proceed with the requests.
如果校验和匹配,则表明OkHTTP连接的证书是真实的,因此我们可以继续进行请求。
OkHTTP is providing CertificatePinner
to make that task easy.
OkHTTP提供了CertificatePinner
来简化该任务。
The implementation looks like this:
实现看起来像这样:
val certificatePinner = CertificatePinner.Builder()
.add("www.domain.com",
// base64encoded SHA256
"sha256/dlpedDsLEvgbase64encodedSHA256ky16vi1obFFn/yOh=")
.build()// set the certificatePinner to OkHTTP builder
val okHttpBuilder = OkHttpClient.Builder()
okHttpBuilder.certificatePinner(certificatePinner)
And that’s it! OkHTTP will now verify that the certificate it connects to, is genuine.
就是这样! OkHTTP现在将验证其连接的证书是真实的。
处理SSL证书到期 (Handling SSL Certificates expiry)
SSL Certificates have an expiry date, which mean the SHA-256 has also an expiry date. When the certificate will become expired, you will have to provide a new SHA-256 fingerprint for the new certificate. Thankfully the CertificatePinner can handle multiple PINs:
SSL证书具有到期日期,这意味着SHA-256也具有到期日期。 证书过期后,您将必须为新证书提供新的SHA-256指纹。 值得庆幸的是,CertificatePinner可以处理多个PIN:
val certificatePinner = CertificatePinner.Builder()
.add("www.domain.com",
// base64encoded SHA256 - old cert
"sha256/oLdCeRtDsLEvgbase64encodedSHA256ky16vi1obFFn/yOh=") .add("www.domain.com",
// base64encoded SHA256 - new cert
"sha256/nEwCeRtldpsDejbase64encodedSHA256ky16vi1obFFn/yOh=") .build()
So if you get the new certificate in advance you can hardcode the new fingerprint into your app and then ask your user to update the app if the fingerprint is expired, so they get the latest version with the new fingerprint.
因此,如果您提前获得了新证书,则可以将新指纹硬编码到您的应用中,然后要求您的用户更新该指纹是否过期的应用,以便他们获得带有新指纹的最新版本。
But there is other technical solutions, like downloading the PINs that you would encrypt on the server and decrypt on the App, using a passphrase, so PINs can dynamically change.
但是,还有其他技术解决方案,例如使用密码短语下载在服务器上加密并在应用程序上解密的PIN,以便PIN可以动态更改。
结论 (Conclusion)
In this article we have seen how OkHTTP with CertificatePinner can help improve the security of your app. Handling certificate expiry can be tricky, but it will improve your app’s security and protect against main-in-the-middle attacks.
在本文中,我们了解了带有CertificatePinner的OkHTTP如何帮助提高应用程序的安全性。 处理证书到期可能很棘手,但是它将提高应用程序的安全性并防止中间人攻击。
ssl pining