2015-04-09 8 views
17

У меня есть base64 открытый ключ, который был создан с помощью Java, используя этот код:Чтение PEM открытый ключ в прошивкой

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

Это приводит строку Base64.

В OSX я могу получить SecKeyRef, используя этот код:

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

Однако в прошивке нет SecKeyCreateFromData метода.

Я могу использовать строку Base64 в прошивкой с помощью this code, который добавляет его к связке ключей, а затем возвращает его снова как SecKeyRef однако я бы предпочел не иметь, чтобы добавить сертификат в брелка просто чтобы быть в состоянии восстановить его использовать его один раз.

Выполнения некоторых исследований, кажется, я должен быть в состоянии использовать SecCertificateCreateWithData создать сертификат для использования в прошивке из строки Base64 у меня есть, но я всегда получаю обратно NULL сертификат при использовании этого кода:

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

Вы видели это [статья] (http://ios-blog.co.uk/tutorials/quick-tips/quick-tip-how-to-get-seckeyref-from-base64-coded-string/)? – Gannic

+0

Да, вот где я получил код выше, но SecCertificateRef всегда имеет значение NULL. – Darren

+0

Вы не хотите получать 'SecKeyRef', а не' SecCertificateRef'? 'SecCertificateCreateWithData' требует, чтобы данные были« A DER (Distinguished Rules Encoding Rules) »в сертификате X.509« – Joshua

ответ

1

Вы не base64-декодируете свои ключевые данные в первую очередь. Вы передаете данные с кодировкой base64 в SecCertificateCreateWithData(), и эта функция ожидает необработанные, декодированные данные. Попробуйте что-нибудь подобное вместо этого:

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

Update:

Что вы отправляете код IOS является base64 DER-закодированные ключ, не PEM или дер-кодированный сертификат. Таким образом, ожидается, что результат, который вы видите, вы даете ему DER-закодированный бланк данных, который не содержит сертификат, и он возвращает вам нулевую ссылку на сертификат, представляющую несуществующие данные сертификата.

У вас есть два варианта:

  1. Используйте код, который вы уже нашли, чтобы добавить ключ в связке ключей, а затем извлечь его. Кажется, это «способ iOS» для импорта ключей для использования в iOS.

  2. Используйте открытый ключ и связанный с ним закрытым ключом, чтобы подписать сертификат и импортировать его в приложение, создать доверительные отношения временных с этим сертификатом, а затем вытащить открытый ключ из информации сертификата (например: iOS SecKeyRef from NSString)

Для второго варианта работы ваш Java-код должен иметь не только открытый ключ, но и соответствующий закрытый ключ для создания подписанного сертификата.

В зависимости от того, что вы планируете делать с SecKeyRef, у вас могут возникнуть проблемы. SecKeyRef значения могут быть приведены прямо к значениям SecKeychainItemRef для использования в функциях Keychain Services. Если значение SecKeyRef не получено из брелка, ваш код получит ошибки. Read the docs for more info

+0

Я не видел комментарий jrtc27 при публикации, но его комментарий - это то же самое, что и мой ответ. – hrunting

+1

Он по-прежнему дает null SecCertificateref! – Darren

Смежные вопросы