9to*_*ios 6 iphone xcode objective-c ios
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
.add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
.add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
.add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
.build();
Run Code Online (Sandbox Code Playgroud)
如何使用NSURLSession方法在IOS中实现相同的任务?
这里有一些参考代码
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
if ([remoteCertificateData isEqualToData:localCertData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
Run Code Online (Sandbox Code Playgroud)
编辑部分
我得到了以下解决方案,在NSURLSession中自动调用委托函数,有人可以解释它是如何工作的吗?还需要发送乘数证书我该怎么做?
(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSString *authMethod = [[challenge protectionSpace] authenticationMethod];
if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
} else {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"MyLocalCertificate" ofType:@"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
NSURLCredential *credential;
if ([remoteCertificateData isEqualToData:localCertData]) {
credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
NSLog(@"Finished Challenge");
}
}
Run Code Online (Sandbox Code Playgroud)
如果身份验证方法是,则 if 块会跳过证书固定NSURLAuthenticationMethodServerTrust。我不太确定你为什么要这样做——你必须查看获得此代码片段的源代码并了解它的要求是什么。
如果身份验证方法是其他方法,则 else 块将执行证书固定。
该变量serverTrust从服务器发送到 SSL 事务状态。这里最主要的是它有一个认证服务器的证书链。下一行certificate设置为链中的叶证书,即服务器的证书。
remoteCertificateData本质上是一个大的二进制 blob,代表证书中的信息。CFBridgingRelease内存管理需要调用(所有函数CFxxx都是C/C++函数,不是Objective-C,内存管理比正常的要复杂一点)。
localCertData是证书本地副本中信息的二进制 blob。请注意,iOS 应用程序(或多或少)是文件的集合,包括可执行文件以及各种资源等。作为构建过程的一部分,您将安排服务器证书的副本包含在这些集合中 ( NSBundle)文件数量。这cerPath变量设置为证书本地副本的文件路径。
最后,我们检查两个二进制 blob 是否相等。如果不是,则来自服务器的证书是伪造的,我们不会继续处理该请求。
我不完全确定“需要发送乘数证书”是什么意思。从您引用的 Java 代码来看,我假设您的意思是您想要将服务器证书与多个本地证书进行比较。在这种情况下,(大致)类似于以下内容(注意:未经测试的代码):
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
BOOL match = NO;
NSURLCredential *credential;
for (NSString *path in [[NSBundle mainBundle] pathsForResourcesOfType:@"cer" inDirectory:@"."]) {
NSData *localCertData = [NSData dataWithContentsOfFile:path];
if ([remoteCertificateData isEqualToData:localCertData]) {
credential = [NSURLCredential credentialForTrust:serverTrust];
match = YES;
break;
}
}
if (match) {
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
NSLog(@"Finished Challenge");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
687 次 |
| 最近记录: |