jjzjj

ios - 带有客户端证书的 SecTrustSetAnchorCertificates

coder 2024-01-20 原文

我正在开发 iOS 应用程序。我们有自签名 ca-cert 的自定义证书颁发机构。证书颁发机构也为用户和 https 服务器颁发证书。我想创建 iOS 应用程序,它可以使用 ca 证书验证 https 服务器,也可以使用客户端证书与 https 服务器通信。我已经有了使用客户端证书与 https 服务器通信的代码,但我需要将 ca 证书导入系统 key 环。我想将 ca 证书硬编码到应用程序中。我的代码如下所示:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {

    bool result=NO;
    if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
        result= YES;
    } else if([protectionSpace authenticationMethod] ==     NSURLAuthenticationMethodClientCertificate) {
        result = YES;
    }
    return result;
}

- (BOOL)shouldTrustProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    CFDataRef certDataRef = (__bridge_retained CFDataRef)self.rootCertData;
    SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);

    SecTrustRef serverTrust = protectionSpace.serverTrust;

    CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert, 1, NULL);
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef);

    SecTrustResultType trustResult;
    SecTrustEvaluate(serverTrust, &trustResult);

    return  trustResult == kSecTrustResultUnspecified;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    NSLog(@"Did receive auth challange %@",[challenge debugDescription]);

    NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];

    NSString *authMethod = [protectionSpace authenticationMethod];
    if(authMethod == NSURLAuthenticationMethodServerTrust ) {
        NSLog(@"Verifying The Trust");

        NSURLCredential* cred=[NSURLCredential credentialForTrust:[protectionSpace serverTrust]];
        if ([self shouldTrustProtectionSpace:challenge.protectionSpace]) {
            [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
            NSLog(@"OK");
        } else {
            NSLog(@"FAILED");
            [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
        }

    }
    if(authMethod == NSURLAuthenticationMethodClientCertificate ) {
        NSLog(@"Trying Certificate");
        .....

一切都很顺利,直到服务器不需要客户端证书。此时我将收到错误消息此服务器的证书无效并且执行永远不会到达点

 NSLog(@"Trying Certificate");

当我将 .der ca-cert 加载到系统 key 环中时,一切正常,甚至客户端证书也被发送到服务器,并且服务器可以识别用户。我认为

SecTrustSetAnchorCertificates(serverTrust, certArrayRef);

以某种方式影响信任,因为当我跳过这个调用时,我可以简单地做:

[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];

没有任何错误,但在这种情况下我无法验证证书。

我做错了什么?

非常感谢, 亚当

最佳答案

看看这段代码

https://github.com/dirkx/Security-Pinning-by-CA

它通过相​​当小心地将两个信任 block 分开(您似乎在混合)来做到这两点。

关于ios - 带有客户端证书的 SecTrustSetAnchorCertificates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15326553/

有关ios - 带有客户端证书的 SecTrustSetAnchorCertificates的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  6. Ruby:如何使用带有散列的 'send' 方法调用方法? - 2

    假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而

  7. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  8. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  9. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  10. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

随机推荐