数字证书中的公钥是否哈希_ios上的公钥哈希固定

数字证书中的公钥是否哈希

The primary purpose of this article is to provide an implementation example of public key hash pinning on iOS.

本文的主要目的是提供iOS上公钥哈希固定的实现示例。

The underlying concepts and theories are not thoroughly explained in this article, although I will provide the sources I used to learn about the topic.

尽管我将提供用于学习该主题的资源,但本文并未对基本概念和理论进行详尽的解释。

什么是固定? (What is Pinning?)

Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or ‘pinned’ to the host.

固定是将主机与其预期的X509证书或公钥相关联的过程。 一旦知道或看到了主机的证书或公钥,便会将证书或公钥关联或“固定”到主机。

from OWASP — Certificate and Public Key Pinning

OWASP提供的证书和公钥固定

In an iOS development context, this means that we want to associate a certificate or a public key to the server we communicate with and only allow communication with the said server.

在iOS开发环境中,这意味着我们要将证书或公钥与我们与之通信的服务器关联,并且仅允许与所述服务器通信。

问题 (The problem)

One application that my company was working on used certificate pinning to ensure the safety of our communication channel.

我公司正在处理的一个应用程序使用了证书固定,以确保我们的通信通道的安全。

This meant that an X509 certificate was bundled with the application, and during each and every request, we compared the server’s certificate to the bundled one, and if they matched, we deemed the channel secure.

这意味着X509证书与应用程序捆绑在一起,在每个请求期间,我们将服务器的证书与捆绑的证书进行比较,如果匹配,我们认为通道是安全的。

This method is considered secure, but it holds a couple of risks:

该方法被认为是安全的,但存在一些风险:

— Because of bundling the certificate in our .ipa, we basically expose it in case of decompilation or reverse-engineering. This is bad enough in itself, but

—由于将证书捆绑在我们的.ipa中,因此在进行反编译或反向工程的情况下,我们基本上将其公开。 这本身就够糟糕的了,但是

— If our server changes its certificate, our app breaks.

—如果我们的服务器更改其证书,则我们的应用程序将中断

These risks have motivated us to find, and implement a more bulletproof method of securing our communication channels.

这些风险促使我们寻找并实施一种更加防弹的方法来保护我们的沟通渠道。

Another motivation was that the Android team working on the same application used a different methodology, which proved to solve the risks mentioned above: this method was to pin the hash of the Public Key of our server’s certificate.

另一个动机是,在同一个应用程序上工作的Android团队使用了不同的方法,事实证明可以解决上述风险:该方法是固定服务器证书的公钥的哈希值

(Solution)

A certificate can be changed in a way that leaves its public key (and its hashed value) intact.

可以以不改变其公钥(及其散列值)的方式更改证书。

This gives us an opportunity to only bundle the hash of the public key of our certificate, and to match it with the hash of the certificate’s public key received during a network request.

这使我们有机会仅捆绑证书的公共密钥的哈希,并将其与在网络请求期间接收到的证书的公共密钥的哈希进行匹配。

Note: hashing is complex and complicated, so I advise you to use algorithms provided by trusted sources, eg. OpenSSL)

注意:杂凑非常复杂,因此,我建议您使用可信任来源提供的算法,例如。 OpenSSL )

This method is more complex than simply pinning the certificates, but we think that it’s well worth it.

这种方法比简单地固定证书要复杂得多,但是我们认为这样做很值得。

Below you can find a list of steps for obtaining the public key hash of your server’s certificate using a handful of OpenSSL commands (common OpenSSL commands):

在下面,您可以找到使用一些OpenSSL命令( 常见的OpenSSL命令 )获取服务器证书的公钥哈希的步骤的列表:

Acquire the certificate of your server. This can be done by either asking for it from your backend developer colleagues, or by simply downloading it from a browser (eg. if your server has a public website).

获取服务器证书。 这可以通过向您的后端开发人员同事要求或通过从浏览器下载(例如,如果您的服务器具有公共网站)来完成。

openssl s_client -connect your-server.com:443 -showcerts < /dev/null | openssl x509 -outform der > server_cert.der

— When you have the certificate, you need to extract and optionally save its public key in a PEM format.

—拥有证书后,您需要提取并选择以PEM格式保存其公钥。

openssl x509 -inform der -in server_cert.der -pubkey -noout > server_cert_public_key.pem

— After having the certificate, you can hash it with whatever hashing algorithm you prefer (only make sure that it is a secure algorithm). I used SHA256 to hash our key. After calculating the hash, I simply encoded it with Base64 encoding, to make it easier to store, and read.

—获得证书后,可以使用您喜欢的任何哈希算法对它进行哈希处理(仅确保它是安全的算法)。 我使用SHA256哈希密钥。 在计算完哈希之后,我只是使用Base64编码对其进行了编码,以使其更易于存储和读取。

cat server_cert_public_key.pem | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

The output of the commands listed above is the hash of your server’s public key, which can now be added to your application.

上面列出的命令的输出是服务器公钥的哈希,现在可以将其添加到您的应用程序中。

实作 (Implementation)

Now that we have our hash, it’s time to make some good use of it.

现在我们有了哈希,是时候充分利用它了。

As you may know, there are many networking libraries used in iOS development, therefore there are many ways to integrate any kind of pinning in your app. Because of this, I will only show you the core of a possible implementation:

如您所知,iOS开发中使用了许多网络库,因此有很多方法可以在您的应用中集成任何类型的固定。 因此,我将仅向您展示可能的实现的核心:

— extracting the public key from the received certificate,

—从收到的证书中提取公钥,

— hashing it,

-对其进行哈希处理

— and matching it to your stored hash.

—并将其与您存储的哈希值匹配。

Note: on iOS, during network communication, you receive a chain of certificates in an object used to evaluate trust (SecTrust). This provided implementation assumes that you store multiple hashes, one hash belonging to the public key of a certificate in this chain.

注意:在iOS上,在网络通信期间,您会在用于评估信任(SecTrust)的对象中收到证书链。 提供的实现假设您存储了多个散列,其中一个散列属于此链中证书的公钥。

公共接口 (Public interface)

Let’s start with the bare structure of our PublicKeyPinner class.

让我们从PublicKeyPinner类的裸结构开始。

We need a property to store the hashes we need to match and a method that validates our trust object. Optionally we can specify the domain from where we plan to receive our trust object.

我们需要一个属性来存储需要匹配的哈希,并需要一个方法来验证我们的信任对象。 (可选)我们可以指定计划从中接收信任对象的域。

验证方式 (Validation)

Now let’s start to implement the body of our validate method. First, if a domain is provided, we need to set it as a SecPolicy:

现在,让我们开始实现validate方法的主体。 首先,如果提供了域,则需要将其设置为SecPolicy

Next, we need to check the validity of our SecTrust object:

接下来,我们需要检查SecTrust对象的有效性:

Now, that we have a valid trust object, it’s time to evaluate its trustiness.

现在,我们有了一个有效的信任对象,是时候评估其信任度了。

To do this, we have to iterate through the chain of certificates contained in the trust object. In each iteration, we have to retrieve the public key data of the current certificate, hash it and compare this hash against our stored hashes:

为此,我们必须遍历信任对象中包含的证书链。 在每次迭代中,我们必须检索当前证书的公钥数据,对其进行哈希处理,然后将此哈希与我们存储的哈希进行比较:

This concludes the validation part of our implementation. There may be many unknown methods in the code snippets above, for reference check out the documentation.

至此,我们实施的验证部分结束了。 上面的代码片段中可能有许多未知的方法,请查阅文档以供参考。

You may notice a reference to the hash(data: Data) method and you guessed it, this is the next and final part of our PublicKeyPinner implementation.

您可能会注意到对hash(data:Data)方法的引用,但您猜对了,这是我们PublicKeyPinner实现的下一部分,也是最后一部分。

散列 (Hashing)

First and foremost, the publicKeyData we saw above is missing some key (😉) information: the ASN1 header for public keys to re-create the subject public key info (more info about this here). Basically, we need an array of unsigned integers that contain an indication of the algorithm, and any algorithm parameters, with which the public key is to be used.

首先,我们在上面看到的publicKeyData缺少一些密钥(😉)信息:用于公共密钥的ASN1标头,用于重新创建主题公共密钥信息(有关更多信息,请参见 此处 )。 基本上,我们需要一个无符号整数数组,其中包含要使用公钥的算法指示以及任何算法参数。

If you remember from earlier in the article, we used OpenSSL-s dgst function with sha256 hashing to create our hashes. To recreate the same hashes in our code, the following bytes are needed:

如果您还记得本文前面的内容,我们将OpenSSL的dgst函数与sha256哈希一起使用来创建哈希。 要在我们的代码中重新创建相同的哈希,需要以下字节:

Now that we have our header, we can implement our hash method. There are many libraries that provide cryptographic functions, for demonstration purposes I will use a 3rd party library (CryptoSwift) and two frameworks provided by Apple: CryptoKit (iOS 13+) and CommonCrypto.

现在有了标头,就可以实现哈希方法。 有许多提供密码功能的库,出于演示目的,我将使用第三方库( CryptoSwift )和Apple提供的两个框架: CryptoKit (iOS 13+)和CommonCrypto

First, let’s see how to use Apple’s new CryptoKit framework, more precisely it’s SHA256 hasher. We create a variable named `keyWithHeader` to store the header and the public key data retrieved from the certificate. If iOS 13 is available, we create a digest of our data and return it’s base64 encoded string.

首先,让我们看看如何使用苹果公司的新CryptoKit框架,更确切地说是SHA256哈希器。 我们创建一个名为`keyWithHeader`的变量来存储标题和从证书中检索到的公共密钥数据。 如果iOS 13可用,我们将创建数据摘要并返回其为base64编码的字符串。

Now let’s see the else branch. Here, we can see two more examples of hashing: one using CommonCrypto and one using CryptoSwift. If you were not delighted enough by the great API provided by the Security framework, CommonCrypto-s API will be a true snack for you!

现在让我们看看else分支。 在这里,我们可以看到另外两个哈希示例:一个使用CommonCrypto,另一个使用CryptoSwift。 如果您对Security框架提供的出色API感到不满意,那么CommonCrypto-s API将是您的不二之选!

CryptoSwift, just like CryptoKit, provides a more elegant way of doing things, having all the magic hidden:

就像CryptoKit一样,CryptoSwift提供了一种更优雅的做事方式,隐藏了所有魔力:

And with that, our PublicKeyPinner is ready for some (secure) action. To view all of the source code in one place, check out this gist.

这样,我们的PublicKeyPinner就可以采取一些(安全的)措施。 要在一个地方查看所有源代码,请查看此要点

摘要 (Summary)

We’ve come a long way in this article, and have touched some complex topics, such as Cryptographic Hashing and Certificate/Public Key Hash pinning.

我们在本文中已经走了很长一段路,并涉及了一些复杂的主题,例如加密哈希和证书/公共密钥哈希固定。

I’ve learned a lot while researching and solving the problems listed above, and I hope you did too by reading this article.

在研究和解决上述问题时,我学到了很多东西,希望您阅读本文也能做到。

Note: if you prefer to use third-party libraries, the functionality of the above implementation (and many more features) can be found in an open-source library called TrustKit.

注意:如果您更喜欢使用第三方库,可以在名为TrustKit的开源库中找到上述实现的功能(以及更多功能)。

At Supercharge, we are a next-generation innovation partner working with our clients to create transformative digital solutions. If you liked this article, check out some of Supercharge’s other articles on our blog, or follow us on LinkedIn, and Facebook. If you’re interested in open positions, follow this link.

Supercharge ,我们是下一代创新合作伙伴,与我们的客户一起创建具有变革意义的数字解决方案。 如果您喜欢这篇文章,请在我们的 博客 上查看Supercharge的其他一些文章 ,或者在 LinkedIn Facebook 上关注我们 如果您对空缺职位感兴趣,请点击此 链接

翻译自: https://medium.com/supercharges-mobile-product-guide/public-key-hash-pinning-on-ios-703ca255cb11

数字证书中的公钥是否哈希

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值