2009-12-23 9 views
8

Di recente ho dovuto configurare CocoaHttpServer, che stiamo utilizzando con successo nella nostra applicazione, per gestire le connessioni HTTPS provenienti da un'applicazione client (in esecuzione su dispositivi Android). Questo va bene: c'è un copioso codice di esempio che consente questo, e siamo stati in grado di abilitare il server sicuro senza problemi.Come si impostano le crittografie SSL quando si utilizza CFSocket/CFStream in Cocoa?

In pratica stavamo assistendo a fasi di negoziazione SSL incredibilmente lunghe mentre il client stava facendo il suo handshake con il nostro server - fino a 70 secondi.

Attraverso una lunga serie di ricerche, ho scoperto che il ritardo era dovuto al calcolo dei parametri Diffie-Hellman utilizzati di default quando SSL è abilitato in CFSocket. Questo thread è il punto in cui ho iniziato a trovare la risposta al mio problema.

Per corrispondere a quello che stava facendo il nostro server Windows (utilizzando una crittografia SSL meno sicura) Avevo bisogno di impostare il cifrario esplicitamente su Mac, il che non è facile quando si usa AsyncSocket come un wrapper per le comunicazioni socket.

server di

nostro di Windows era utilizzando: TLS_RSA_WITH_RC4_128_MD5) (0x04) RC4 a 128 bit MD5 RSA

server di

nostro Macintosh stava usando: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x039) AES 256 bit SHA-1 Ephemeral Diffie-Hellman scambio di chiavi usando il certificato RSA

La differenza in "sicurezza" è grande, ma probabilmente non vale lo sforzo/calcolo/ritardo che stavamo vedendo. Teatro della sicurezza?

+0

Un +1 per i tuoi sforzi, e per il funzionamento della frase "Teatro della sicurezza?" nel tuo post :-) –

+1

Questo è utile, ma dovresti dividere la risposta e postarla come risposta a questa domanda, quindi questa non può vivere per sempre nella pagina senza risposta. (È totalmente kosher rispondere alla tua stessa domanda). – benzado

risposta

4

Si prega di notare che ci sono diversi codici che possono essere scelti - Ho scelto di utilizzare lo stesso come la nostra implementazione di Windows per coerenza.

Con informazioni da another question di cui sopra, ho capito come impostare il cifrario per CFSocket di utilizzare lo stesso di Windows, e il codice sembra essere ormai un po 'meglio - come funziona davvero! CFSocket non espone direttamente il supporto di SecureTransport, il che rende questo tipo di hard, ma la definizione di una particolare chiave lo rende efficace.

Ai posteri, ecco il codice che ho aggiunto al -onSocketWillConnect: nella nostra classe HTTPConnection:

// define this value; it isn't exposed by CFSocketStream.h 
const extern CFStringRef kCFStreamPropertySocketSSLContext; 

...

CFReadStreamRef stream = [sock getCFReadStream]; 
CFDataRef data = (CFDataRef) CFReadStreamCopyProperty(stream, kCFStreamPropertySocketSSLContext); 

// Extract the SSLContextRef from the CFData 
SSLContextRef sslContext; 
CFDataGetBytes(data, CFRangeMake(0, sizeof(SSLContextRef)), (UInt8*)&sslContext); 
SSLCipherSuite *ciphers = (SSLCipherSuite *)malloc(1 * sizeof(SSLCipherSuite)); 
ciphers[0] = SSL_RSA_WITH_RC4_128_MD5; // Basic cipher - not Diffie-Hellman 
SSLSetEnabledCiphers(sslContext, ciphers, 1); 

Spero che questo aiuta tutti coloro che lavorano con lo stesso problema come me, sarei felice di condividere qualche altro codice e consiglio se necessario.

0

Per quello che vale, ho contribuito con uno patch a CocoaAsyncSocket circa una settimana prima che si verificasse questo problema. Mi dispiace di non aver notato la tua domanda allora. :-)