如何在 iOS 上固定证书的公钥 [英] How to pin the Public key of a certificate on iOS

查看:27
本文介绍了如何在 iOS 上固定证书的公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在提高我们正在开发的 iOS 应用程序的安全性的同时,我们发现需要对服务器的 SSL 证书(全部或部分)进行 PIN 码以防止中间人攻击.

While improving the security of an iOS application that we are developing, we found the need to PIN (the entire or parts of) the SSL certificate of server to prevent man-in-the-middle attacks.

尽管有多种方法可以做到这一点,但当您搜索此内容时,我只找到了固定整个证书的示例.这种做法带来了一个问题:证书一更新,您的应用程序将无法再连接.如果您选择固定公钥而不是整个证书,您会发现自己(我相信)处于同样安全的情况,同时对服务器中的证书更新更具弹性.

Even though there are various approaches to do this, when you searching for thisI only found examples for pinning the entire certificate. Such practice poses a problem: As soon as the certificate is updated, your application will not be able to connect anymore. If you choose to pin the public key instead of the entire certificate you will find yourself (I believe) in an equally secure situation, while being more resilient to certificate updates in the server.

但是你是怎么做到的?

推荐答案

如果您需要知道如何从 iOS 代码的证书中提取此信息,这里有一种方法可以做到.

In case you are in need of knowing how to extract this information from the certificate in your iOS code, here you have one way to do it.

首先添加安全框架.

#import <Security/Security.h>

添加 openssl 库.您可以从 https://github.com/st3fan/ios-openssl

The add the openssl libraries. You can download them from https://github.com/st3fan/ios-openssl

#import <openssl/x509.h>

NSURLConnectionDelegate 协议允许您决定连接是否应该能够响应保护空间.简而言之,此时您可以查看来自服务器的证书,并决定允许连接继续还是取消.您在这里要做的是将证书公钥与您固定的公钥进行比较.现在的问题是,你如何获得这样的公钥?看看下面的代码:

The NSURLConnectionDelegate Protocol allows you to decide whether the connection should be able to respond to a protection space. In a nutshell, this is when you can have a look at the certificate that is coming from the server, and decide to allow the connection to proceed or to cancel. What you want to do here is compare the certificates public key with the one you've pinned. Now the question is, how do you get such public key? Have a look at the following code:

首先获取 X509 格式的证书(为此您需要 ssl 库)

First get the certificate in X509 format (you will need the ssl libraries for this)

const unsigned char *certificateDataBytes = (const unsigned char *)[serverCertificateData bytes];
X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [serverCertificateData length]);

现在准备读取公钥数据

ASN1_BIT_STRING *pubKey2 = X509_get0_pubkey_bitstr(certificateX509);

NSString *publicKeyString = [[NSString alloc] init];    

此时可以遍历pubKey2字符串,将HEX格式的字节提取成字符串,如下循环

At this point you can iterate through the pubKey2 string and extract the bytes in HEX format into a string with the following loop

 for (int i = 0; i < pubKey2->length; i++)
{
    NSString *aString = [NSString stringWithFormat:@"%02x", pubKey2->data[i]];
    publicKeyString = [publicKeyString stringByAppendingString:aString];
}

打印公钥查看

 NSLog(@"%@", publicKeyString);

完整代码

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
const unsigned char *certificateDataBytes = (const unsigned char *)[serverCertificateData bytes];
X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [serverCertificateData length]);
ASN1_BIT_STRING *pubKey2 = X509_get0_pubkey_bitstr(certificateX509);

NSString *publicKeyString = [[NSString alloc] init];    

for (int i = 0; i < pubKey2->length; i++)
 {
     NSString *aString = [NSString stringWithFormat:@"%02x", pubKey2->data[i]];
     publicKeyString = [publicKeyString stringByAppendingString:aString];
 }

if ([publicKeyString isEqual:myPinnedPublicKeyString]){
    NSLog(@"YES THEY ARE EQUAL, PROCEED");
    return YES;
}else{
   NSLog(@"Security Breach");
   [connection cancel];
   return NO;
}

}

这篇关于如何在 iOS 上固定证书的公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆