Cifrado de iOS utilizando el file de key pública RSA en formatting DER

Estoy intentando usar una key pública RSA para cifrar datos dentro de una aplicación de iOS para enviarlos al service de un cliente a través de la web. La key se generó usando openssl:

openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -pubout -out public.der -outform der 

Luego trato de usar la key de la siguiente manera:

 NSString *aPublicKeyPath = [[NSBundle mainBundle] pathForResource:@"public" ofType:@"der"]; NSFileManager* aFileMgr = [NSFileManager defaultManager]; NSData* myCertData = [aFileMgr contentsAtPath: aPublicKeyPath]; CFDataRef myCertDataRef = (__bridge CFDataRef)myCertData; SecCertificateRef cert = SecCertificateCreateWithData (kCFAllocatorDefault, myCertDataRef); 

El contenido de la certificación se carga correctamente en myCertData, pero SecCertificateCreateWithData no devuelve ningún file sin lanzar una exception. No hay un código de resultado para verificar, así que no sé por qué no funciona.

FYI: la key aparece válida. Si reviso la key, obtengo este resultado:

 $ openssl rsa -text -in public.der -inform DER -pubin Modulus (2048 bit): 00:a7:21:90:62:96:15:38:f8:43:5b:33:9f:00:a0: 12:51:63:0e:5c:72:58:05:6a:99:93:d8:6e:f4:d8: 4a:91:cb:dc:74:de:3c:38:63:06:41:5f:63:1e:e9: 70:81:90:e9:f0:e4:78:0a:00:5c:d3:ee:6a:5a:c1: d7:9a:62:af:f3:45:91:5a:86:bc:aa:8f:86:f5:4f: 3d:01:4b:64:11:31:6f:c1:ab:07:e5:b8:5b:46:8e: b5:c0:a1:2c:7b:65:1b:09:a9:12:b4:99:f8:77:46: fa:62:52:04:32:98:09:1c:69:89:52:8c:30:77:af: 51:f2:30:0d:99:33:d3:2b:39:6c:6b:0e:19:ad:67: 10:69:0f:4e:3c:7a:a4:41:bd:87:4e:1d:65:b7:62: 7e:0d:b5:f7:ab:3d:b8:40:f1:c9:8c:c3:1e:9e:7c: 02:67:3a:21:ca:3a:3c:cd:d8:98:fe:4c:ab:30:d4: f8:2d:3e:78:c3:f0:39:54:15:8a:b7:16:77:ca:3b: ab:42:5e:70:3e:48:fd:a3:6c:55:5e:66:4b:33:d6: c0:9c:db:2d:d2:26:78:b8:ca:69:6c:77:6d:38:ab: 77:a0:68:ad:e5:2d:11:50:57:b6:16:dc:b3:e2:82: bb:07:88:08:a4:87:4c:c6:37:9e:33:ea:5a:f9:b4: 0c:6f Exponent: 65537 (0x10001) writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApyGQYpYVOPhDWzOfAKAS UWMOXHJYBWqZk9hu9NhKkcvcdN48OGMGQV9jHulwgZDp8OR4CgBc0+5qWsHXmmKv 80WRWoa8qo+G9U89AUtkETFvwasH5bhbRo61wKEse2UbCakStJn4d0b6YlIEMpgJ HGmJUowwd69R8jANmTPTKzlsaw4ZrWcQaQ9OPHqkQb2HTh1lt2J+DbX3qz24QPHJ jMMennwCZzohyjo8zdiY/kyrMNT4LT54w/A5VBWKtxZ3yjurQl5wPkj9o2xVXmZL M9bAnNst0iZ4uMppbHdtOKt3oGit5S0RUFe2Ftyz4oK7B4gIpIdMxjeeM+pa+bQM bwIDAQAB -----END PUBLIC KEY----- 

¿Alguna sugerencia?

ACTUALIZAR:

iOS no parece admitir la lectura directa de una key pública como se generó anteriormente sin una piratería grave, consulte esta publicación de blog donde el encabezado público se elimina manualmente de la key para que se cargue . Pude hacer que esto funcione, pero creo que no es un buen enfoque para poner en mi aplicación.

Finalmente obtuve una solución con la que estoy contento. Como se indica en la documentation, el certificate debe estar en formatting DER, así que lo regeneré usando este command y funcionó:

 $ openssl req -x509 -out public_key.crt -outform DER -new -newkey rsa:4096 -keyout private_key.pem 

Luego utilizo la key de la siguiente manera:

 NSString *aPublicKeyPath = [[NSBundle mainBundle] pathForResource:@"public" ofType:@"der"]; NSFileManager* aFileMgr = [NSFileManager defaultManager]; NSData* aCertData = [aFileMgr contentsAtPath: aPublicKeyPath]; SecCertificateRef aCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)aCertData); if (aCertRef != NULL) { SecKeyRef aPublicKeyRef = NULL; SecTrustRef aTrustRef = NULL; SecPolicyRef aPolicyRef = SecPolicyCreateBasicX509(); if (aPolicyRef) { if (SecTrustCreateWithCertificates((CFTypeRef)aCertRef, aPolicyRef, &aTrustRef) == noErr) { SecTrustResultType result; if (SecTrustEvaluate(aTrustRef, &result) == noErr) { aPublicKeyRef = SecTrustCopyPublicKey(aTrustRef); } } } if (aPolicyRef) CFRelease(aPolicyRef); if (aTrustRef) CFRelease(aTrustRef); if (aCertRef) CFRelease(aCertRef); NSString* aClearTextString = @"This is the test string"; NSString* aEncryptedString = [[self class] encryptRSA:aClearTextString key:aPublicKeyRef]; } 

La rutina de encryption es:

 +(NSString *)encryptRSA:(NSString *)plainTextString key:(SecKeyRef)publicKey { size_t cipherBufferSize = SecKeyGetBlockSize(publicKey); uint8_t *cipherBuffer = malloc(cipherBufferSize); uint8_t *nonce = (uint8_t *)[plainTextString UTF8String]; SecKeyEncrypt(publicKey, kSecPaddingOAEP, nonce, strlen( (char*)nonce ), &cipherBuffer[0], &cipherBufferSize); NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize]; return [encryptedData base64EncodedStringWithOptions:0]; } 

Consulte la documentation en https://developer.apple.com/library/ios/documentation/Security/Reference/certifkeytrustservices/#//apple_ref/c/func/SecCertificateCreateWithData

Estás intentando cargar la key pública. Esta API espera un certificate de key pública, no una key pública.

Dice

Devuelve NULL si los datos pasados ​​en el parámetro de datos no son válidos con el certificate DER-codificado X.509 .

Por lo tanto, haga pública la key o utilice otra API para cargar la key pública.