Esto debería hacer lo que está pidiendo: encripta los datos con la clave pública del servidor. No está sujeto a ataques MITM, a menos que el atacante tenga una copia de su clave privada y su contraseña (comunicarse a través de un sistema no SSL, sin embargo, aún lo es, pero los datos que encripte con la clave pública legítima del servidor serán casi imposibles de descifrar) .
Construí esto en conjunto con los documentos de Apple, este sitio, los foros de desarrolladores de Apple y probablemente en otros lugares. ¡Así que gracias a todos los que he descifrado el código! Este código se supone varias cosas:
Usted ya ha generado sus pares de claves RSA (estoy usando una clave de 4096 bits y parece lo suficientemente rápida) y, utilizando la clave privada, crea un DER codificada certificado llamado "cert.cer" que coloca en su paquete de recursos de su aplicación (obviamente, también puede descargar el certificado de su servidor, pero luego está abierto a ataques MITM de nuevo). De forma predeterminada, OpenSSL genera un certificado codificado PEM, por lo que debe convertirlo con "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS se descartará en PEM. La razón por la que uso un certificado es que en realidad es más fácil trabajar con él y es compatible con iOS. Usar solo la clave pública no es (aunque se puede hacer).
Ha agregado Security.framework a su proyecto y #import <Security/Security.h>.
/* Devuelve un NSData del texto cifrado, o nil si el cifrado no tuvo éxito.
Toma el certificado X.509 como NSData (de dataWithContentsOfFile :, por ejemplo) */
+(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];
}
No es una cuestión por lo que puedo ver. –
Lo siento Greg. Acabo de agregar una pregunta. –
Esto no será seguro sin SSL; estará sujeto a un [hombre en el ataque medio] (http://en.wikipedia.org/wiki/Man_in_the_middle_attack). – cobbal