java ios objective-c ssl rsa

java - Leyendo la clave pública PEM en iOS



objective-c ssl (1)

Tengo una clave 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 obtener 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 cadena Base64 en iOS usando este código que lo agrega al llavero, luego lo recupero nuevamente como SecKeyRef sin embargo, preferiría no agregar el certificado al llavero solo para poder recuperarlo y usarlo una vez.

Al investigar un poco, parece que debería poder usar SecCertificateCreateWithData para crear un certificado para usar en iOS desde la cadena Base64 que tengo, sin embargo, siempre obtengo un certificado 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); } }


Usted no está descifrando en base64 sus datos clave primero. Usted está pasando datos codificados en base64 a SecCertificateCreateWithData() , y esa función espera los datos descodificados en bruto. Intenta 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 clave codificada DER de base64, no un certificado codificado DER o PEM. Como tal, se espera el resultado que está viendo: le da un blob de datos con codificación DER que no contiene un certificado y le devuelve una referencia de certificado nula que representa los datos de certificados que no existen.

Tienes dos opciones:

  1. Use el código que ya encontró para agregar la llave al llavero y luego búsquelo. Esa parece ser la "manera de iOS" para importar claves para su uso en iOS.

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

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

Dependiendo de lo que planee hacer con el SecKeyRef , puede tener problemas. SecKeyRef valores de SecKeyRef se pueden convertir directamente a los valores de SecKeychainItemRef para su uso en las funciones de Servicios de llavero. Si el valor SecKeyRef no proviene del llavero, su código obtendrá errores. Lea la documentación para más información