作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在提高我们正在开发的 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/
我是一名优秀的程序员,十分优秀!