gpt4 book ai didi

macos - 具有真实证书的 Ocj-C 安全套接字服务器 - SSL 协议(protocol)错误(基于 GCDAsyncSockets)

转载 作者:太空宇宙 更新时间:2023-11-03 14:10:14 26 4
gpt4 key购买 nike

我一直在为一个奇怪的问题苦苦思索 - 一些似乎没有说导出(或完全不同的术语)的问题。令人惊讶的是,我找不到 HTTPS 示例 - 我找到的所有内容都有这个“待办事项”!

简而言之:

我正在尝试使用有效证书创建一个使用 TLS 的“服务器”。

问题:

一旦我成功导入证书,为 GCDAsyncSockets 设置设置,然后调用 startTLS,连接将立即断开“SecureTransport 错误 -9800”- Chrome 称之为“ERR_SSL_PROTOCOL_ERROR”

测试:

  1. 运行服务器。
  2. 通过 Chrome 或 Safari(https://localhosthttps://localhost:somefreeport)连接。
  3. 尝试根据收到的数据观察页面请求。
  4. 在握手阶段观察失败。

Chrome 是我选择的测试平台,因为此练习稍后将处理 WebSocket 流量 - 因此我使用有效的证书,而不是自签名的。

长描述:

使用 GCDAsyncSocket 监听一个端口,然后一旦我收到一个连接,我就使用那个套接字和“startTLS”来处理它。(我并不排斥使用 GCDAsyncSocket,只是我在客户端套接字中熟悉它使用明文和 TLS,以及服务器明文 - 只有服务器 TLS 让我感到困惑)。

该证书是具有已知公共(public) CA(Comodo 或 GoDaddy)的签名证书 - 我已经在 .Net 中成功使用它下面的源将成功打开证书并报告对等名称。然而,.Net 简化了很多,所以比较起来并不简单。 (将传递的证书加载到 x509 对象中,然后应用于新套接字。而在这里,我也必须定义密码和 SSL 版本)。

简化的代码示例:

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
//Get certificate
NSString* p12Path = [[NSBundle bundleForClass:[self class]] pathForResource:@"mySignedCert"
ofType:@"pfx"];
CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain([[NSData alloc] initWithContentsOfFile:p12Path]);

CFStringRef password = CFSTR("myCertPassword"); //Cert Password
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);

OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
CFRelease(options);
CFRelease(password);

if(securityError == errSecSuccess)
NSLog(@"Success opening p12 certificate."); //All good!
else
return nil;

CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef myIdent = (SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);

SecIdentityRef certArray[1] = { myIdent };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);

//Build TLS settings dictionary
[self willSecureWithSettings:settings]; //This just uses SSLGetNumberSupportedCiphers & SSLGetSupportedCiphers to create a cipher array and appends to settings
settings[(NSString *)kCFStreamSSLCertificates] = (__bridge id)(myCerts);
settings[(NSString *)kCFStreamSSLPeerName] = @"my.peer.address";

/* Valid values for protocol types
kSSLProtocolUnknown = 0, no protocol negotiated/specified; use default
kSSLProtocol3 = 2, SSL 3.0
kTLSProtocol1 = 4, TLS 1.0
kTLSProtocol11 = 7, TLS 1.1
kTLSProtocol12 = 8, TLS 1.2
kDTLSProtocol1 = 9, DTLS 1.0
*/

//Tried 0,2,4,7,8 - 9 throws another error, possibly unsupported.
settings[GCDAsyncSocketSSLProtocolVersionMin] = [NSNumber numberWithInteger:8];
settings[GCDAsyncSocketSSLProtocolVersionMax] = [NSNumber numberWithInteger:8];

[newSocket startTLS:settings];
[newSocket readDataWithTimeout:-1 tag:0];
}

我发现了很多旧的例子,没有一个再适用了(不使用旧的 GCDAsyncSocket 或旧的 Xcode)。我发现最接近的提到后来的“GCDAsyncSocketSSLProtocolVersionMin/Max”设置为 2,例如 Chrome 不支持它。

有没有人成功并愿意分享一些建议?

亲切的问候,KF。

最佳答案

哇——我花了很多时间解决这个问题,然后在这里寻求提示。

10 分钟后想通了!

我的改变:

//THIS! Tried prior, but GCDAsyncSocket docs stated not-needed, plus was getting different handshake errors.
settings[(NSString *)kCFStreamSSLIsServer] = [NSNumber numberWithBool:YES];

其他 SO 用户可能会觉得有用的其他更改:

//Apparently prefereable
settings[(NSString*)kCFStreamPropertyShouldCloseNativeSocket] = [NSNumber numberWithBool:YES];
//Above example was both matching for test. 4-8 was always preferable.
settings[GCDAsyncSocketSSLProtocolVersionMin] = [NSNumber numberWithInteger:4];
settings[GCDAsyncSocketSSLProtocolVersionMax] = [NSNumber numberWithInteger:8];

非常感谢 - 即使您支持 Rubber Ducking!

关于macos - 具有真实证书的 Ocj-C 安全套接字服务器 - SSL 协议(protocol)错误(基于 GCDAsyncSockets),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32334434/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com