2015-04-09 4 views
17

ho una chiave pubblica Base64 che è stato generato da Java utilizzando questo codice:lettura PEM chiave pubblica in iOS

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); 

Questo si traduce in una stringa Base64.

In OSX posso ottenere un SecKeyRef utilizzando questo codice:

// 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); 

Tuttavia in iOS non esiste un metodo SecKeyCreateFromData.

posso utilizzare la stringa Base64 in iOS utilizzando this code che aggiunge al portachiavi, poi recupera di nuovo come un SecKeyRef tuttavia Preferirei mille volte non è necessario aggiungere il CERT al portachiavi solo per essere in grado di recuperarla usarlo una volta.

Facendo qualche ricerca, sembra che dovrei essere in grado di utilizzare SecCertificateCreateWithData per creare un certificato da utilizzare in iOS dalla stringa Base64 che ho, ma ho sempre tornare un CERT NULL quando si utilizza questo codice:

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); 
    } 
} 
+0

hai visto questo [articolo] (http://ios-blog.co.uk/tutorials/quick-tips/quick-tip-how-to-get-seckeyref-from-base64-coded-string/)? – Gannic

+0

Sì, è da lì che ho ricevuto il codice sopra, ma SecCertificateRef è sempre NULL. – Darren

+0

Non vuoi ottenere un 'SecKeyRef' piuttosto che un' SecCertificateRef'? 'SecCertificateCreateWithData' richiede che i dati siano 'A DER (Distinguished Encoding Rules) rappresentazione di un certificato X.509' – Joshua

risposta

1

Non si sta decodificando in base64 i dati chiave per primi. Stai trasmettendo dati codificati in base 64 su SecCertificateCreateWithData() e tale funzione si aspetta i dati grezzi e decodificati. Provare qualcosa di simile, invece:

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

Aggiornamento:

cosa si sta inviando al codice iOS è la chiave DER con codifica Base64, non un DER o certificato PEM codificato. Come tale, il risultato che si sta vedendo è previsto - gli dai un BLOB di dati codificati DER che non contiene un certificato e ti restituisce un riferimento certificato null che rappresenta i dati del certificato inesistente.

si hanno due opzioni:

  1. utilizzare il codice che avete già trovato per aggiungere la chiave al portachiavi e poi prenderlo fuori. Questo sembra essere il "modo iOS" per importare le chiavi da utilizzare su iOS.

  2. Usare la chiave pubblica e la chiave privata associata a firmare un certificato e importare che nella vostra applicazione, creare un rapporto di fiducia temporanea con tale certificato, quindi estrarre la chiave pubblica di informazioni del certificato (ad esempio: iOS SecKeyRef from NSString)

Affinché la seconda opzione funzioni, il codice Java non deve solo avere la chiave pubblica, ma avrà anche bisogno della chiave privata associata per generare un certificato firmato.

A seconda di cosa si intende fare con lo SecKeyRef, è possibile che si verifichino problemi. I valori SecKeyRef possono essere convertiti direttamente nei valori SecKeychainItemRef da utilizzare nelle funzioni dei servizi portachiavi. Se il valore SecKeyRef non proviene dal portachiavi, il codice riceverà errori. Read the docs for more info

+0

Non ho visto il commento di jrtc27 quando ho postato, ma il suo commento è la stessa cosa della mia risposta. – hrunting

+1

Fornisce ancora un SecCertificateref nullo! – Darren