Leyendo la key pública de PEM en iOS

Tengo una key pública base64 que fue generada por Java usando este código:

RSAPublicKeySpec rsaKS = new RSAPublicKeySpec(modulus, pubExponent); RSAPublicKey rsaPubKey = (RSAPublicKey) kf.generatePublic(rsaKS); byte[] encoded = rsaPubKey.getEncoded(); String base64 = Base64.encodeToString(encoded, Base64.DEFAULT); Log.e(null, "base64: " + base64); 

Esto da como resultado una cadena Base64.

En OSX puedo get un SecKeyRef usando este código:

 // Create the SecKeyRef using the key data CFErrorRef error = NULL; CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA); CFDictionarySetValue(parameters, kSecAttrKeyClass, kSecAttrKeyClassPublic); SecKeyRef keyRef = SecKeyCreateFromData(parameters, (__bridge CFDataRef)[pubKey base64DecodedData], &error); 

Sin embargo, en iOS no hay SecKeyCreateFromData método SecKeyCreateFromData .

Puedo usar la secuencia Base64 en iOS usando este código que lo agrega al llavero, luego lo recupera nuevamente como un SecKeyRef sin embargo, preferiría no tener que agregar el certificate al llavero solo para poder recuperarlo para usarlo una vez.

Al hacer una investigación, parece que debería poder utilizar SecCertificateCreateWithData para crear un certificate para usar en iOS desde la cadena Base64 que tengo, sin embargo, siempre obtengo un certificate NULL cuando uso este código:

 NSString* pespublicKey = @"MIGfMA0GCSqGSIb3....DCUdz/y4B2sf+q5n+QIDAQAB"; NSData* certData = [pespublicKey dataUsingEncoding:NSUTF8StringEncoding]; SecCertificateRef cert; if ([certData length]) { cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); if (cert != NULL) { CFStringRef certSummary = SecCertificateCopySubjectSummary(cert); NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString*)certSummary]; NSLog(@"CERT SUMMARY: %@", summaryString); CFRelease(certSummary); } else { NSLog(@" *** ERROR *** trying to create the SSL certificate from data located at %@, but failed", pespublicKey); } } 

No estás descodificando en base64 tus datos key primero. Está pasando datos codificados en base64 a SecCertificateCreateWithData() , y esa function espera los datos sin SecCertificateCreateWithData() y decodificados. Pruebe algo como esto en su lugar:

 NSData *certData = [[NSData alloc] initWithBase64EncodedString:pespublicKey options:0]; cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); 

Actualizar:

Lo que está enviando a su código iOS es la key codificada DER base64, no un certificate codificado DER o PEM. Como tal, se espera el resultado que está viendo: le proporciona una burbuja de datos codificada DER que no contiene un certificate y le devuelve una reference de certificate nulo que representa los datos de certificate inexistentes.

Tienes dos opciones:

  1. Use el código que ya ha encontrado para agregar la llave al llavero y luego searchlo. Esa parece ser la "forma de iOS" para importar keys para usar en iOS.

  2. Utilice la key pública y su key privada asociada para firmar un certificate e importarlo a su aplicación, crear una relación de confianza temporal con ese certificate y luego extraer la key pública de la información del certificate (ejemplo: iOS SecKeyRef de NSString )

Para que la segunda opción funcione, su código Java no solo tendrá que tener la key pública, sino que también necesitará la key privada asociada para generar un certificate firmado.

Dependiendo de lo que planifique hacer con el SecKeyRef , puede encontrarse con problemas. SecKeyRef valores de SecKeyRef pueden SecKeyRef directamente a los valores de SecKeychainItemRef para su uso en las funciones de los services de Keychain. Si el valor SecKeyRef no proviene del llavero, su código obtendrá errores. Lea los documentos para más información