Questo dovrebbe fare ciò che stai chiedendo: crittografa i dati con la chiave pubblica del server. Non è soggetto agli attacchi MITM, a meno che l'attaccante non abbia una copia della chiave privata e la sua password (comunicare via non SSL, tuttavia, lo è ancora, ma i dati che crittografate con la chiave pubblica legittima del server saranno quasi impossibili da decifrare) .
L'ho lazzato insieme dai documenti di Apple, questo sito, i forum degli sviluppatori Apple e probabilmente altrove. Quindi grazie a tutti ho aggiunto il codice! Questo codice presuppone diverse cose:
Hai già generato le vostre coppie di chiavi RSA (sto usando una chiave a 4096 bit e sembra abbastanza veloce) e, utilizzando la chiave privata, ha creato una codifica DER certificato chiamato "cert.cer" che hai inserito nel pacchetto di risorse della tua app (ovviamente, puoi anche scaricare il certificato dal tuo server, ma poi sarai nuovamente aperto agli attacchi MITM). Per impostazione predefinita, OpenSSL genera un certificato codificato PEM, quindi è necessario convertirlo con "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS barf su PEM. Il motivo per cui utilizzo un certificato è in realtà più semplice da utilizzare e supportato in iOS. Usare solo la chiave pubblica non è (anche se può essere fatto).
Hai aggiunto Security.framework al progetto e si #import <Sicurezza/Security.h>.
/* Restituisce un NSData del testo cifrato, o nullo se la crittografia non ha avuto successo.
è del certificato X.509 come NSData (da dataWithContentsOfFile :, ad esempio) */
+(NSData *)encryptString:(NSString *)plainText withX509Certificate:(NSData *)certificate {
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificate);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
OSStatus status = SecTrustCreateWithCertificates(cert, policy, &trust);
SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(trust, &trustResult);
}
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
const char *plain_text = [plainText UTF8String];
size_t blockSize = SecKeyGetBlockSize(publicKey);
NSMutableData *collectedCipherData = [NSMutableData data];
BOOL success = YES;
size_t cipherBufferSize = blockSize;
uint8_t *cipherBuffer = malloc(blockSize);
int i;
for (i = 0; i < strlen(plain_text); i += blockSize-11) {
int j;
for (j = 0; j < blockSize-11 && plain_text[i+j] != '\0'; ++j) {
cipherBuffer[j] = plain_text[i+j];
}
int result;
if ((result = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, cipherBuffer, j, cipherBuffer, &cipherBufferSize)) == errSecSuccess) {
[collectedCipherData appendBytes:cipherBuffer length:cipherBufferSize];
} else {
success = NO;
break;
}
}
/* Free the Security Framework Five! */
CFRelease(cert);
CFRelease(policy);
CFRelease(trust);
CFRelease(publicKey);
free(cipherBuffer);
if (!success) {
return nil;
}
return [NSData dataWithData:collectedCipherData];
}
Non una domanda, per quanto posso vedere. –
Mi dispiace Greg. Ho appena aggiunto una domanda. –
Questo non sarà sicuro senza SSL; sarà soggetto a un attacco [man in the middle] (http://en.wikipedia.org/wiki/Man_in_the_middle_attack). – cobbal