ssl实现_如何快速实现ssl固定

ssl实现

Privacy — like eating and breathing — is one of life’s basic requirements.

饮食和呼吸等隐私是生活的基本要求之一。

— Katherine Neville

—凯瑟琳·内维尔

Nearly every iOS app communicates with servers to retrieve information. Sometimes this information is sensitive and you don’t want anyone to be able to access them (for example, their username and password to sign in to the app).

几乎每个iOS应用程序都与服务器通信以检索信息。 有时,此信息很敏感,您不希望任何人都能访问它们(例如,他们的用户名和密码登录到该应用程序)。

At the launch of iOS 9, Apple introduced App Transport Security, which forces apps to use a secure network connection by adopting HTTPS protocol and Transport Layer Security (TLS). What does this mean? It means our apps can’t communicate with a server through a non-secure connection. Actually, it’s possible to bypass this restriction but to avoid potential attacks, it’s not recommended.

在iOS 9的发布中,Apple引入了App Transport Security ,该应用程序通过采用HTTPS协议和Transport Layer Security(TLS)来强制应用程序使用安全的网络连接。 这是什么意思? 这意味着我们的应用程序无法通过非安全连接与服务器通信。 实际上,可以绕过此限制,但是为了避免潜在的攻击,不建议这样做。

So my data is safe, right? The answer is no! Even if TLS protects the transmitted data, it’s easier for an attacker to set up man-in-the-middle attacks using hacked or self-signed certificates. This means they can capture data moving to and from your app.

所以我的数据是安全的,对吗? 答案是不! 即使TLS保护了传输的数据,攻击者也更容易使用被黑客入侵或自签名证书来设置中间人攻击 。 这意味着他们可以捕获往返于您的应用程序的数据。

In this article, I’ll explain how to prevent these kind of attacks in order to make your app data safe. We will cover some basic knowledge on the following topics:

在本文中,我将解释如何防止此类攻击以使您的应用程序数据安全。 我们将涵盖以下主题的一些基本知识:

TLS(传输层安全性) (TLS (Transport Layer Security))

First, we need to understand how TLS and man-in-the-middle attacks work, to understand how to prevent them. TLS allows you to transmit data over a secure network, following three phases:

首先,我们需要了解TLS和中间人 攻击有效,了解如何预防。 TLS允许您按照以下三个阶段通过安全网络传输数据:

  • The client initiates a connection with the server by sending a message that includes the supported version of TLS and the cipher suite used for encryption. The server responds with the selected cipher suites and a digital certificate. The client verifies that those digital certificates are authentic (i.e. issued by a certificate authority).

    客户端通过发送一条消息来启动与服务器的连接,该消息包括支持的TLS版本和用于加密的密码套件 。 服务器以选定的密码套件和数字证书作为响应。 客户端验证那些数字证书是真实的(即,由证书颁发机构颁发)。

  • If the validation succeeds, the client generates a pre-master key encrypted with the server’s public key included in the certificate. The server decrypts the secret with its private key. Both use this secret to generate a master key.

    如果验证成功,则客户端将生成一个预主密钥,该预主密钥将使用证书中包含的服务器公钥进行加密。 服务器使用其私钥解密机密。 两者都使用此机密来生成主密钥。
  • Both use encryption of plaintext and decryption of ciphertext by using the master key and symmetric encryption.

    两者都通过使用主密钥和对称加密来使用明文加密和密文解密。

But, what is a certificate? A certificate is proof of identity of the server. It’s just a file that contains information about the server that owns the certificate and follows the X.509 standard. The client only trusts a server that can provide a valid certificate signed by one of the trusted Certificate Authorities, otherwise, the connection will be aborted.

但是,什么是证书? 证书是服务器身份的证明。 它只是一个文件,其中包含有关拥有证书并遵循X.509标准的服务器的信息。 客户端仅信任可以提供由受信任的证书颁发机构之一签名的有效证书的服务器,否则,连接将被中止。

In order to validate it, the app verifies:

为了验证它,该应用程序验证:

  • The expiry date.

    到期日。
  • The digital signature.

    数字签名。

中间人 (The Man-In-The-Middle)

A man-in-the-middle is an attack in which the attacker secretly listens and eventually alters the communication between two parties. It’s easier than you may think to use this kind of attack to intercept data that an app is sending to a server. All you need is a SSL Proxy Server.

中间人是一种攻击,其中攻击者秘密侦听并最终更改了两方之间的通信。 使用这种攻击来拦截应用程序发送到服务器的数据比您想像的要容易。 您只需要一个SSL代理服务器。

The SSL proxy performs encryption and decryption between the client and the server (the keys are different for both direction). An example is Charles. It sits between your app and the internet and you can inspect and even change data midstream to test how your app responds.

SSL代理在客户端和服务器之间执行加密和解密(两个方向的密钥不同)。 查尔斯就是一个例子。 它位于您的应用程序和互联网之间,您可以检查甚至更改数据流,以测试应用程序的响应方式。

  • Your app encrypts data with the Charles ProxyCertificate public’s key, instead of the server’s. The Charles Certificate is validated because the developer can install it in his device.

    您的应用使用Charles ProxyCertificate公用密钥而不是服务器的公用密钥加密数据。 查尔斯证书已通过验证,因为开发人员可以将其安装在他的设备中。
  • Charles is able to decrypt all data with its private key and then communicate with the server using the server’s public key.

    Charles能够使用其私钥解密所有数据,然后使用服务器的公钥与服务器进行通信。

This means that any developer can read all the data that your app is sending over the network!

这意味着任何开发人员都可以读取您的应用程序通过网络发送的所有数据!

Here’s how to set up Charles.

这是设置Charles的方法

SSL固定 (SSL Pinning)

Fortunately, there’s a simple way to prevent this kind of attack through a technique called SSL Pinning.

幸运的是,有一种简单的方法可以通过称为SSL Pinning的技术来防止此类攻击。

This technique validates the server certificates again, even after SSL handshaking. The developer embeds a list of trustful certificates inside the client application and compare them with the server certificates during runtime. In case of a mismatch between the server’s certificates and the local copy, the connection is simply aborted.

即使在SSL握手之后,此技术也会再次验证服务器证书。 开发人员将可信任证书列表嵌入到客户端应用程序中,并在运行时将它们与服务器证书进行比较。 如果服务器的证书与本地副本不匹配,则连接将被中止。

This means that the app will check the Charles’s certificate and, even if it’s trusted, it will be different from the local certificate embedded inside the app.

这意味着该应用程序将检查Charles的证书,即使该证书受信任,它也将与应用程序中嵌入的本地证书不同。

One con is that a pinned certificate has an expiration date and this requires an app update, unless the developer also pins future certificates inside the app. Actually, instead of pinning the whole certificate, you can just use the hashed public key (this is a better approach because we can reuse the same hashed key also in future certificates).

一个弊端是,固定证书的有效期截止,这需要应用程序更新,除非开发人员还将将来的证书固定在应用程序内。 实际上,除了固定整个证书之外,您还可以使用散列的公钥(这是一种更好的方法,因为我们也可以在以后的证书中重用同一散列的密钥)。

固定在Swift中 (Pinning in Swift)

Evaluating trust is a two-step process.

评估信任是一个两步过程。

  • Validate the certificate’s digital signature. Your app can rely on any of the root certificates embedded in iOS or you can supply your own.

    验证证书的数字签名。 您的应用程序可以依赖iOS中嵌入的任何根证书,也可以提供自己的证书。

  • Testing the certificate against a trust policy. The policy indicates how particular fields or extensions of a certificate should be in order to be trusted.

    根据信任策略测试证书。 该策略指示证书的特定字段或扩展应该如何被信任。

All of this activity is facilitated by an instance of the SecTrust object that you prepare with one or more certificates and policy objects.

通过使用一个或多个证书和策略对象准备的SecTrust对象的实例,可以简化所有这些活动。

准备证书 (Prepare the certificate)

Apple provides the SecCertificate to represent a X.509 certificate. If you add the certificate inside the bundle you can retrieve it with:

Apple提供了代表X.509证书的SecCertificate 。 如果将证书添加到捆绑包中,则可以使用以下方法检索它:

let filePath = Bundle.main.path(forResource: name, ofType: type)!let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))let certificate = SecCertificateCreateWithData(nil, data as CFData)

Here you can find also more complex solutions — for example, using keychain and identity. There isn’t a “best” solution, because it mostly depends on the problem and on the level of security you need in your app. I suggest you read up and try them all, then decide which one suits your needs.

在这里,您还可以找到更复杂的解决方案-例如,使用钥匙串和身份。 没有“最佳”解决方案,因为它主要取决于问题和应用程序所需的安全级别。 我建议您阅读并尝试所有这些内容,然后再决定哪个适合您的需求。

制定政策 (Prepare a policy)

The best option is usually to use one of the predefined policies. For example, you could use the standard basic policy for X509 certificates with:

最好的选择通常是使用预定义策略之一。 例如,您可以将X509证书的标准基本策略用于:

let policies = 

This is probably enough for your app, but if you need more flexibility you can create your own SSL policy with the SecPolicyCreateSSL(_:_:).

这对于您的应用程序可能已经足够,但是如果您需要更大的灵活性,则可以使用SecPolicyCreateSSL(_:_:)创建自己的SSL策略。

秘密信托 (The SecTrust)

Now it’s time to validate both certificates and policies. Apple facilitates all these operations with a SecTrust object.

现在是时候验证证书和策略了。 Apple通过SecTrust对象简化了所有这些操作。

var optionalTrust: SecTrust?
let status = SecTrustCreateWithCertificates(certArray as AnyObject,
policy,
&optionalTrust)
guard status == errSecSuccess else { return }
let trust = optionalTrust!

SecTrustCreateWithCertificates(_:_:_:) creates a trust management object based on the provided certificates and policies.

SecTrustCreateWithCertificates(_:_:_:)基于提供的证书和策略创建信任管理对象。

You can use SecTrustEvaluateWithError(_:_:) to validate a trust object. From the documentation:

您可以使用SecTrustEvaluateWithError(_:_:)来验证信任对象。 从文档中:

This method evaluates a certificate’s validity to establish trust for a particular use — for example, in creating a digital signature or to establish a Secure Sockets Layer connection. The method validates a certificate by verifying its signature plus the signatures of the certificates in its certificate chain, up to the anchor certificate, according to the policy or policies included in the trust management object.

此方法评估证书的有效性以建立对特定用途的信任-例如,在创建数字签名或建立安全套接字层连接时。 该方法通过根据信任管理对象中包含的一个或多个策略,通过验证其签名以及其证书链中证书的签名(直到锚定证书),来验证证书。

If the trust management instance lacks some of the certificates needed to verify the leaf certificate, SecTrustEvaluateWithError(_:_:) searches for certificates:

如果信任管理实例缺少验证叶证书所需的某些证书​​,则SecTrustEvaluateWithError(_:_:)搜索证书:

- In the user’s keychain.

-在用户的钥匙串中。

- Among any certificates you previously provided by calling SecTrustSetAnchorCertificates(_:_:).

-在先前通过调用SecTrustSetAnchorCertificates(_:_ :)提供的所有证书中。

- In a system-provided set of keychains provided for this purpose.

-为此目的提供的一组系统提供的钥匙串。

- Over the network, if certain extensions are present in the certificate used to build the chain.

-通过网络,如果用于构建链的证书中存在某些扩展名。

The only thing that you need now is to evaluate the SecTrust that you receive during a network call with your policies and compare the certificate with the one pinned inside the app.

现在,您唯一需要做的就是用SecTrust将您在网络通话期间收到的SecTrust进行评估,并将证书与固定在应用程序中的证书进行比较。

Let’s take a look at an example:

让我们看一个例子:

This is a simple example, but there are many other parameters and objects to handle all the possible validations of a SecTrust. I suggest you carefully read all the documentation provided by Apple and test it before trying to use it in your app.

这是一个简单的示例,但是还有许多其他参数和对象可以处理SecTrust所有可能的验证。 我建议您在尝试在应用程序中使用它之前,仔细阅读Apple提供的所有文档并进行测试。

Here the main link.

这里是主要环节。

用Alamofire 5固定 (Pinning with Alamofire 5)

As you can see, using the normal API is quite complex. I recommend using Alamofire, an external library that provides a higher level of API making your life simpler.

如您所见,使用常规API非常复杂。 我建议使用Alamofire ,这是一个提供更高级别API的外部库,使您的生活更简单。

Everything is based on the ServerTrustEvaluating protocol that provides a way to perform any sort of server trust evaluation. Alamofire includes many different types of trust evaluators, for example:

一切都基于ServerTrustEvaluating协议,该协议提供了一种执行任何类型的服务器信任评估的方法。 Alamofire包括许多不同类型的信任评估器,例如:

  • DefaultTrustEvaluator: Allows you to control whether to validate the host provided by the challenge.

    DefaultTrustEvaluator :允许您控制是否验证质询提供的主机。

  • RevocationTrustEvaluator: Checks the status of the received certificate to ensure it hasn’t been revoked.

    RevocationTrustEvaluator :检查收到的证书的状态,以确保它尚未被吊销。

  • PinnedCertificatesTrustEvaluator: The server trust is considered valid if one of the pinned certificates matches one of the server certificates.

    PinnedCertificatesTrustEvaluator :如果固定证书之一与服务器证书之一匹配,则服务器信任被视为有效。

  • PublicKeysTrustEvaluator: The server trust is considered valid if one of the pinned public keys matches one of the server certificate’s public keys.

    PublicKeysTrustEvaluator :如果固定的公用密钥之一与服务器证书的公用密钥之一匹配,则认为服务器信任有效。

You only have to choose which ServerTrustEvaluating to use for each API:

您只需要选择对每个API使用哪个ServerTrustEvaluating

let evaluators: [String: ServerTrustEvaluating] = [
"cert.example.com": PinnedCertificatesTrustEvalutor(),
]
let manager = ServerTrustManager(evaluators: serverTrustPolicies)

Then create a session with them:

然后与他们创建会话:

let serverTrustManager = ServerTrustManager(evaluators: evaluators)self.session = Session(serverTrustManager: serverTrustManager)

You can read the full documentation here.

您可以在此处阅读完整的文档。

如何下载证书 (How to Download a Certificate)

If you want to do some tests or you need to validate a public API you can download the certificate and pin it to your app.

如果要进行一些测试或需要验证公共API,则可以下载证书并将其固定到您的应用程序。

Open your terminal and write the following:

打开您的终端并输入以下内容:

openssl s_client -connect <url>:443 </dev/null \
| openssl x509 -outform DER -out <filename>.der

This will download the certificate into your current folder.

这会将证书下载到您当前的文件夹中。

I hope you enjoyed the article! Fell free to reach out to me if you have any doubts.

希望您喜欢这篇文章! 如有任何疑问,请随时与我联系。

翻译自: https://medium.com/better-programming/how-to-implement-ssl-pinning-in-swift-7c4e8f6ee821

ssl实现

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值