将PEM公钥读入iOS

我有一个由java使用这个代码生成的base64公钥:

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

这导致Base64string。

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

但是在iOS中没有SecKeyCreateFromData方法。

我可以在iOS中使用Base64string,使用这个代码将其添加到钥匙串,然后再次作为SecKeyRef检索它,但我宁愿不必将证书添加到钥匙串只是为了能够检索到使用它一旦。

做了一些研究,似乎我应该能够使用SecCertificateCreateWithData来创build一个证书,使用iOS中的Base64string我有,但是我总是得到一个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); } } 

你不是base64-首先解码你的关键数据。 您正在将base64编码的数据传递给SecCertificateCreateWithData() ,并且该函数需要原始的解码数据。 尝试这样的事情,而不是:

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

更新:

您发送给您的iOS代码的是base64 DER编码的密钥,而不是DER或PEM编码的证书。 因此,您所看到的结果是预期的 – 您给它一个DER编码的数据blob,它不包含证书,它将返回一个空证书引用,表示不存在的证书数据。

你有两个select:

  1. 使用您已经find的代码将钥匙添加到钥匙串,然后将其取出。 这似乎是导入在iOS上使用密钥的“iOS方式”。

  2. 使用公共密钥及其相关私钥签名证书并将其导入到应用程序中,与该证书build立临时信任关系,然后将公钥从证书信息中拉出(例如: NSString中的iOS SecKeyRef )

对于第二个选项来说,Java代码不仅需要拥有公钥,还需要相关的私钥来生成签名证书。

根据你打算如何使用SecKeyRef ,你可能会遇到问题。 SecKeyRef值可以直接转换为SecKeychainItemRef值,以用于Keychain Services函数。 如果SecKeyRef值不是来自钥匙串,您的代码将会出错。 阅读文档以获取更多信息