无法使用自定义CA打开安全websocket [英] Unable to open secure websocket using custom CA

查看:180
本文介绍了无法使用自定义CA打开安全websocket的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用socket.io的iOS应用程序( socket.io-objc library)连接本地和远程服务器。我与远程服务器的连接已经使用了TLS而没有任何问题。远程服务器具有由知名CA签名的证书。现在我想要使用本地连接。但是,这些本地证书不可能由知名CA签名。

I am writing an iOS application that uses socket.io (the socket.io-objc library) to connect to local and remote servers. My connection to the remote server already uses TLS without any problems. The remote servers have certificates that are signed by a well-known CA. Now I want to secure the local connection using as well. However, it is not possible for these local certs to be signed by a well-known CA.

到目前为止,我已经生成了一个自定义CA证书,并用它来签署本地服务器的证书。我相信这是有效的,因为如果我手动将CA证书安装到我的iPad上,我就可以连接到服务器了。

So far, I've generated a custom CA certificate and used that to sign the local server's certificate. I believe this is working because if i manually install the CA cert onto my iPad i am able to connect to the server.

现在我正在尝试使用本文作为参考。我遇到的问题是,虽然看起来我可以成功将证书添加到我的应用程序的钥匙串,但我的套接字连接似乎没有使用它。

Now I'm trying to install the CA certificate automatically in the application using this article as a reference. The problem I'm having is that although it appears I can successfully add the certificate to my app's keychain, my socket connection does not seem to be using it.

启动时,我的应用程序安装CA:

On startup, my app installs the CA:

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSData *iosTrustedCertDerData = [NSData dataWithContentsOfFile:[bundle pathForResource:@"myRootCA" ofType:@"der"]];
SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef) iosTrustedCertDerData);

CFDictionaryRef dict = (__bridge CFDictionaryRef)([NSDictionary dictionaryWithObjectsAndKeys:
                        (__bridge id) (kSecClassCertificate), kSecClass,
                        certificate, kSecValueRef,
                        nil]);

OSStatus err = SecItemAdd(dict, NULL);
if (err == noErr) {
    NSLog(@"####### IT WORKS!!!!!!!!!");
}
else if (err == errSecDuplicateItem) {
    NSLog(@"###### IT WAS ALREADY THERE!!!");
}
else {
    NSLog(@"####### IT BROKEN!!!!!!!!");
}

第一次运行时,它打印出IT WORKS。现在它打印出它已经在那里。这是预期的。然后,当我尝试连接时,我就像正常一样打开我的socket.io连接

The first time this ran, it printed out "IT WORKS". Now it prints out "IT WAS ALREADY THERE". This is as expected. Then, when I try to connect I just open my socket.io connection like normal

SocketIO* socketIO = [[SocketIO alloc] initWithDelegate:self];
socketIO.useSecure = YES;
[socketIO connectToHost:url onPort:port];

这会导致错误:


此服务器的证书无效。您可能正在连接到假装为myserver.local的服务器,这可能会使您的机密信息面临风险。

The certificate for this server is invalid. You might be connecting to a server that is pretending to be "myserver.local" which could put your confidential information at risk.

再次,如果我手动安装证书,那么一切正常。我的所有搜索都是如何以编程方式将证书点添加/信任回SecItemAdd。但这似乎对我不起作用。是否可以使用管理套接字连接的socket.io-obj和SocketRocket库来添加/信任自定义CA证书?

Again, if i install the cert manually then everything works fine. All of my searches for how to programmatically add/trust a cert point back to SecItemAdd. But this does not appear to be working for me. Is it possible to add/trust a custom CA cert using socket.io-obj and SocketRocket libraries that are managing the socket connection?

注意:我不想完全禁用证书验证,我也不想接受所有自签名证书。如果可能,我宁愿只接受由我的自定义CA(和默认的可信CA)签名的证书。

Note: I do not want to completely disable certificate validation nor do I want to accept all self-signed certificates. If possible, i would prefer to accept only certificates that were signed by my custom CA (and the default trusted CAs).

推荐答案

我从未听说过能够将证书添加到应用程序的可信锚点。通常,这只能通过iPhone配置实用程序在设备级别完成。这就是手动的意思吗? (即安装它以便Safari也会尊重它?)如果你读到你链接的博客文章的评论,你会注意到Heath(谁是一个非常聪明的人,所以在我不同意之前我很小心) ,请注意:

I've never heard of being able to add a certificate to the application's trusted anchors. Generally, this can only be done at the device level through the iPhone Configuration Utility. Is that what you mean by "manually?" (i.e. installing it such that Safari would also honor it?) If you read down into the comments of the blog post you link, you note that Heath (who is a really smart guy, so I'm careful before I disagree with him), notes that:


NOT 在钥匙串中添加证书。我正在创建一个SecTrust对象并使用它来验证连接。您只能使用iPhone配置实用程序将证书添加到钥匙串。除非你在钥匙串上添加证书,否则我怀疑NSURLConnection会正常工作。

I’m NOT adding a cert to the keychain. I’m creating a SecTrust object and using it to authenticate the connection. You can only add certs to the keychain with the iPhone Configuration Utility. Unless you add a cert to the keychain, I doubt NSURLConnection would work properly.

这符合我的经验和考试。 (我不知道为什么他说接下来,你可以将你的证书添加到你的应用程序的钥匙串。当你希望iOS为你创建的每个新套接字信任你的证书时,这是合适的。)

That matches my experience and tests. (I don't know why he says "Next, you can add your cert to your app’s keychain. This is appropriate when you want iOS to trust your cert for every new socket you create.")

根据我的经验,你必须为 NSURLConnection 实现身份验证委托方法并执行 SecTrustEvaluate 你自己。 以下是此示例。

In my experience, you have to implement the authentication delegate methods for NSURLConnection and perform the SecTrustEvaluate yourself. Here's an example of that.

请记住,确实只有一个钥匙串;它只有访问组,使你看起来像你有一个私人钥匙串。据我所知,在每个人共享的钥匙串中只有一个可靠的锚列表。

Remember, there really is only one keychain; there are just access groups into it that make it kind of look like you have a private keychain. And there is, as far as I've ever discovered, only one trusted anchor list in that keychain, shared by everyone.

这对你没什么帮助socket.io,因为它不允许您访问其 NSURLConnection 委托方法。您必须修改socket.io以接受信任锚。

This doesn't help you a lot with socket.io, because it doesn't give you access to its NSURLConnection delegate methods. You'd have to modify socket.io to accept a trust anchor.

您可以找到演示文稿,实用安全,很有用。从第5页开始。这是上面的示例代码来自的地方。

You may find the presentation, Practical Security, useful. Start around page 5. This is where the example code above comes from.

这篇关于无法使用自定义CA打开安全websocket的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆