[英]SocketRocket and iOS certificate pinning
我目前正在使用SocketRocket作为iOS应用程序的WebSocket实现,并希望通过SR_SSLPinnedCertificates属性将服务器的CA固定为受信任的证书。 我正在寻找加载一个或多个证书以传递到SocketRocket的好例子。 我有下面的代码可以工作,但是我不确定它是否正确或者是否有更直接的方法。
CFArrayRef keyref = NULL;
NSString *path = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"p12"];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
OSStatus status = SecPKCS12Import((__bridge CFDataRef)data, (__bridge CFDictionaryRef)[NSDictionary dictionaryWithObject:@"eftl_key_pass" forKey:(__bridge id)kSecImportExportPassphrase], &keyref);
if (status == noErr) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyref, 0);
SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecCertificateRef certRef = NULL;
SecIdentityCopyCertificate(identityRef, &certRef);
}
因此,使用SocketRocket进行证书固定:
首先,我们需要从NSURLRequest
而不是从NSURL初始化SocketRocket。
NSURL *url = [[NSURL alloc] initWithString:@"wss://path-to-socket:1234"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
然后,让我们设置证书。 证书必须采用二进制DER格式,而不是base64编码的PEM,这一点至关重要。 证书文件应位于您的主捆绑包中。
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"myOwnCertificate" ofType:@"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:cerPath];
CFDataRef certDataRef = (__bridge CFDataRef)certData;
SecCertificateRef certRef = SecCertificateCreateWithData(NULL, certDataRef);
id certificate = (__bridge id)certRef;
然后,我们将请求的固定证书设置为仅包含我们先前设置的证书的数组。
[request setSR_SSLPinnedCertificates:@[certificate]];
现在我们可以完成套接字了。
SRWebSocket *socket = [[SRWebSocket alloc] initWithURLRequest:request];
[socket open];
对于Swift中的代码:
if let pinnedCertificatePath = NSBundle.mainBundle().pathForResource("subdomain.yourwebsite.com", ofType: "der"),
let pinnedCertificateData = NSData(contentsOfFile: pinnedCertificatePath),
let cert = SecCertificateCreateWithData(nil, pinnedCertificateData) {
request.SR_SSLPinnedCertificates = [cert]
// make the websocket call!
let ws = SRWebSocket(URLRequest: request)
// configure the websocket
ws.open()
} else {
NSLog("Failed to open websocket, could not find pinned certificate!")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.