2013-10-07 22 views
8

sto cercando di impostare una connessione sicura a uno SSLServerSocket eseguire Java.connessione SSL Socket iOS

Ho creato il mio CA principale, e ho firmato il certificato che lo SSLServerSocket Java utilizzando questo certificato.

voglio aggiungere questo certificato principale per la mia app in modo che qualsiasi certificato firmato dal certificato principale funzionerà.

Finora ho la connessione sicura lavorando bene impostando la lettura e scrittura proprietà del flusso a questo:

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys: 
(id)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamPropertySocketSecurityLevel, 
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates, 
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots, 
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,nil]; 

aggiungo il certificato al portachiavi in ​​questo modo:

-(void)addRootCert{ 
NSString* rootCertPath = [[NSBundle mainBundle] pathForResource:@"rootCA" ofType:@"der"]; 
NSData* rootCertData = [NSData dataWithContentsOfFile:rootCertPath]; 

OSStatus err = noErr; 
SecCertificateRef rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)rootCertData); 
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassCertificate, kSecClass, rootCert, kSecValueRef, nil]; 

err = SecItemAdd((__bridge CFDictionaryRef) dict, NULL); 
if (err == noErr) { 
    NSLog(@"Sucessfully added root certificate"); 
}else if (err == errSecDuplicateItem){ 
    NSLog(@"Root certificate already exists"); 
}else{ 
    NSLog(@"Root certificate add failed"); 
} 
} 

Questo è bene, ma voglio convalidare la catena di certificati, in modo che la mia app accetta solo certificati firmati dal mio CA (o quelli di fiducia di default)

Come posso fare questo?

Se ho impostato kCFStreamSSLValidatesCertificateChain di sì, ottengo l'errore: CFNetwork SSLHandshake failed (-9807) ma se è no, non importa che ha firmato il certificato del server, si collegherà a prescindere (suppongo che è di destra?)

Grazie!

risposta

6

Technote 2232, "HTTPS Server Fiducia Evaluation", dovrebbe avere tutte le risposte che cerchi. C'è una documentazione e diversi esempi su come valutare la fiducia del server.

+0

Grazie per questo collegamento, seguendo quello che dice sull'uso di "SecTrustSetAnchorCertificates" Voglio aggiungere il mio root ca a questo, ma non ho un "SecTrustRef', come posso crearne uno? Tutti gli esempi che ho visto sta utilizzando 'metodi delegato NSURLConnection', ma sto usando prese .. –

+3

Questo è probabilmente quello che stai cercando: https://developer.apple.com/library/mac/documentation/NetworkingInternet /Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html – quellish

+0

Grazie, l'ultimo collegamento era perfetto! –

0

Ho avuto questo stesso problema, e aggiungendo manualmente il certificato non risolvere il problema, che significa anche dover aggiornare l'applicazione ogni volta il certificato relativo ai cambiamenti del server (ad esempio, quando scade, che, a mio caso, stava per accadere nel giro di pochi giorni).

Se si sta utilizzando un indirizzo IP per connettersi al socket e il certificato è per il FQDN (nome di dominio completo, ad esempio sottodominio.esempio.com), quindi quando il sistema operativo verifica il certificato, è andando a guardare l'indirizzo IP a cui ti stai connettendo, confrontalo con il nome nel certificato e pensa che i due siano diversi, causando la mancata convalida della catena.

Quindi per chiunque si imbattesse in questo problema, si consiglia di utilizzare il nome FQDN nel secondo parametro su CFStreamCreatePairWithSocketToHost anziché sull'indirizzo IP. Dopodiché, dovrebbe funzionare senza dovendo includere il certificato nel pacchetto e convalidarlo manualmente.