Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
相互SSL/TLS身份验证:从iOS返回Node.js将进行身份验证的证书_Ios_Node.js_Authentication_Ssl - Fatal编程技术网

相互SSL/TLS身份验证:从iOS返回Node.js将进行身份验证的证书

相互SSL/TLS身份验证:从iOS返回Node.js将进行身份验证的证书,ios,node.js,authentication,ssl,Ios,Node.js,Authentication,Ssl,我创建了一个概念验证Node.js HTTPS服务器,其中包含来自可信CA的服务器证书(my-server.crt和my-server.key),并创建了自己的CA以创建客户端证书(CA.crt、client.key、client.crt和client.p12)。使用cURL和客户机PEM证书,我可以成功地使用这些客户机证书进行身份验证。但是,由于iOS客户端代码给出得更深,使用主捆绑包中嵌入的client.p12证书,我无法进行身份验证 这是我的简单Node.js服务器 #!/usr/bin/

我创建了一个概念验证Node.js HTTPS服务器,其中包含来自可信CA的服务器证书(my-server.crt和my-server.key),并创建了自己的CA以创建客户端证书(CA.crt、client.key、client.crt和client.p12)。使用cURL和客户机PEM证书,我可以成功地使用这些客户机证书进行身份验证。但是,由于iOS客户端代码给出得更深,使用主捆绑包中嵌入的client.p12证书,我无法进行身份验证

这是我的简单Node.js服务器

#!/usr/bin/env node
'use strict';

var https = require('https');
var http = require('http');
var fs = require('fs');


var port = process.argv[2] || 8043;
var insecurePort = process.argv[3] || 4080;

//
// Certificates
//
//Sync file reads- not for production
var options = {
  key: fs.readFileSync("certs/my-server.key")
  , cert: fs.readFileSync("certs/my-server.crt")
  , ca: fs.readFileSync("certs/ca.crt")
  , requestCert: true
  , rejectUnauthorized: true
};

//
// HTTPS 
//
var server = https.createServer(options, function (req, res) {
    if (req.client.authorized) {
        res.writeHead(200, {"Content-Type": "application/json"});
        res.end('{"status":"approved"}');
    } else {
        res.writeHead(401, {"Content-Type": "application/json"});
        res.end('{"status":"denied"}');
    }
});
server.listen(port, function(){
  console.log("\nListening for HTTPS traffic on port: " + port);
});

//
// HTTP
//
var insecureServer = http.createServer();
insecureServer.on('request', function (req, res) {

    res.writeHead(200, {"Content-Type": "application/json"}); 
    res.write('{"status":"insecure"}');
    res.end();

});
insecureServer.listen(insecurePort, function(){
  console.log("\nListening for HTTP traffic on port: " + insecurePort);
});
然后用这个cURL语句:

curl -v -s -k --key certs/client.key --cert certs/client.crt https://127.0.0.1:8043
我已成功通过身份验证(来自cURL的输出):

以下是我在iOS应用程序中的代码片段:

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

       return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

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

        NSString *p12Path = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
        NSData *p12Data = [[NSData alloc] initWithContentsOfFile:p12Path];

        CFStringRef password = CFSTR("DoubleTrouble");
        const void *keys[] = { kSecImportExportPassphrase };
        const void *values[] = { password };
        CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
        CFArrayRef p12Items;

        OSStatus result = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);

        if(result == noErr) {

            NSLog(@"Certificate Imported OK");
            CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
            SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);

            SecCertificateRef certRef;
            SecIdentityCopyCertificate(identityApp, &certRef);

            SecCertificateRef certArray[1] = { certRef };
            CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
            CFRelease(certRef);

            NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp certificates:(__bridge NSArray *)myCerts persistence:NSURLCredentialPersistencePermanent];

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

             CFRelease(myCerts);
        }
}
以下是我在XCode控制台中得到的信息:

2015-08-30 10:19:13.213 MutualTLS[3117:298681] Certificate Imported OK
2015-08-30 10:19:13.332 MutualTLS[3117:298763] CFNetwork SSLHandshake failed (-9806)
2015-08-30 10:19:13.394 MutualTLS[3117:298763] CFNetwork SSLHandshake failed (-9806)
2015-08-30 10:19:13.454 MutualTLS[3117:298763] CFNetwork SSLHandshake failed (-9806)
2015-08-30 10:19:13.455 MutualTLS[3117:298763] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9806)
2015-08-30 10:19:13.457 MutualTLS[3117:298681] Error retrieving data, An SSL error has occurred and a secure connection to the server cannot be made.
当然,如果我在Node.js中创建HTTPS服务器的选项中设置rejectUnauthorized=false,则请求被接受,但仍然没有经过身份验证

2015-08-30 10:25:57.558 MutualTLS[3117:298681] Certificate Imported OK
2015-08-30 10:25:57.749 MutualTLS[3117:298681] {"status":"denied"}
我知道我可以保持拒绝=false,然后简单地返回

[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

但这并非不受MITM利用的影响。如果您有任何建议,我们将不胜感激。

为什么您认为这会导致MITM攻击?我怀疑iOS应用程序没有发送客户端证书。Wireshark将帮助您确认这一点。我并没有说它会导致MITM攻击,我说它不会对MITM攻击无动于衷。相互SSL/TLS身份验证的全部目的是帮助防止MITM攻击,并建议在需要额外安全级别的情况下,例如金融交易。在Wireshark中,我看到iOS客户端TLS1.2(在服务器的HELLO消息之后)响应证书、客户端密钥交换、更改密码规范,和2条加密握手信息。似乎缺少一条证书验证消息。我对使用Wireshark调试SSL相当陌生,因此不确定该如何处理。@MrTree您是否怀疑服务器接收到空请求-未收到证书-我在服务器上登录时发现了这一点。我看不出我创建证书的方式有任何错误,并且在提交证书时没有收到返回的错误。想法?为什么你认为这会导致MITM攻击?我怀疑iOS应用程序没有发送客户端证书。Wireshark将帮助您确认这一点。我并没有说它会导致MITM攻击,我说它不会对MITM攻击无动于衷。相互SSL/TLS身份验证的全部目的是帮助防止MITM攻击,并建议在需要额外安全级别的情况下,例如金融交易。在Wireshark中,我看到iOS客户端TLS1.2(在服务器的HELLO消息之后)响应证书、客户端密钥交换、更改密码规范,和2条加密握手信息。似乎缺少一条证书验证消息。我对使用Wireshark调试SSL相当陌生,因此不确定该如何处理。@MrTree您是否怀疑服务器接收到空请求-未收到证书-我在服务器上登录时发现了这一点。我看不出我创建证书的方式有任何错误,并且在提交证书时没有收到返回的错误。思想?
2015-08-30 10:25:57.558 MutualTLS[3117:298681] Certificate Imported OK
2015-08-30 10:25:57.749 MutualTLS[3117:298681] {"status":"denied"}
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];