iphone - 如何在 iOS 上固定证书的公钥

标签 iphone ios ipad security ssl

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

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

但是你是怎么做到的呢?

最佳答案

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

首先添加安全框架。

#import <Security/Security.h>

添加 openssl 库。您可以从 https://github.com/st3fan/ios-openssl 下载它们

#import <openssl/x509.h>

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

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

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格式的字节提取成字符串,循环如下

 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;
}

}

关于iphone - 如何在 iOS 上固定证书的公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15728636/

相关文章:

ios - 作为主屏幕启动的 Web 应用程序在页面更改后切换到浏览器模式

iphone - 如何从 NSNotification 对象获取数据?

iphone - 释放自定义单元格类应用程序中的对象时崩溃

iphone - UIButton 标签为零

ios - 如何以编程方式设置 UINavigationbar 的背景颜色?

ios - Facebook 登录权限 API

iphone - CoreFoundation 中的 CFStringGetLength 导致 iOS 崩溃

iphone - 适用于 iPhone 的 Appdelegate,但不适用于 iPad 版本

iphone - 我想使用 NSSortDescriptor 对数组进行排序

iphone - 如何更改 iOS Kif 测试的顺序?