2

現在、iOS アプリケーションの WebSocket 実装として SocketRocket を使用しており、SR_SSLPinnedCertificates プロパティを使用して、サーバーの CA を信頼できる証明書として固定したいと考えています。SocketRocket に渡す 1 つ以上の証明書を読み込む良い例を探しています。次のコードが機能するようになりましたが、それが正しいかどうか、またはより簡単なアプローチがあるかどうかはわかりません。

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);
}
4

2 に答える 2

5

SocketRocket による証明書のピン留めは、次のように行われます。

NSURLRequestまず、 NSURL からではなくから SocketRocket を初期化する必要があります。

NSURL *url = [[NSURL alloc] initWithString:@"wss://path-to-socket:1234"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

それでは、証明書を設定しましょう。証明書は、base64 でエンコードされた PEM ではなく、バイナリ DER 形式であることが重要です。証明書ファイルはメイン バンドルにある必要があります。

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];
于 2014-08-30T01:28:13.220 に答える
1

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!")
}
于 2016-08-01T21:39:03.507 に答える