将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:
-
使用您已经find的代码将钥匙添加到钥匙串,然后将其取出。 这似乎是导入在iOS上使用密钥的“iOS方式”。
-
使用公共密钥及其相关私钥签名证书并将其导入到应用程序中,与该证书build立临时信任关系,然后将公钥从证书信息中拉出(例如: NSString中的iOS SecKeyRef )
对于第二个选项来说,Java代码不仅需要拥有公钥,还需要相关的私钥来生成签名证书。
根据你打算如何使用SecKeyRef
,你可能会遇到问题。 SecKeyRef
值可以直接转换为SecKeychainItemRef
值,以用于Keychain Services函数。 如果SecKeyRef
值不是来自钥匙串,您的代码将会出错。 阅读文档以获取更多信息