我意识到我在Stack Overflow上已经提出的问题有很多类似的问题,但是没有一个问题有明确的答案可以满足我的需求,所以我们走了:
我的程序通过网络接收ASN.1编码的RSA公钥。我将数据存储在一个简单的NSData实例中。我希望使用该公钥来编码16个字节的数据并通过网络返回这些数据。根据我的研究,最好的方法是使用SecKeyRef。根据Apple提供的荒谬模糊的文档,可以使用一些代码来完成。但是,他们的代码存在问题。每次我想使用公钥时,我都需要将其添加到钥匙串并为其提供唯一标识符。这个问题是这个密钥只用一次。我正在寻找一种方法来获取一个不在钥匙串中的密钥的SecKeyRef,并且是从ASN.1编码密钥创建的。
我还考虑过通过base64编码将它转换为普通PEM并将其包装在'----- BEGIN PUBLIC KEY -----'和'----- END PUBLIC KEY--的可能性---'然后将它加载到SecKeyRef中,但我还没有看到这样做的方法。
另外,我在键,键格式等方面没有太多选择。它来自第三方java服务器。耶。
我目前有这种加载密钥的替代方法(可能)不会将它们添加到密钥链,但密钥显然(通过反复试验:D)不是DER格式,因此我无法加载它像这样。
SecCertificateRef certificateRef = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)data); //data contains the public key - received over the network
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
SecTrustRef trustRef;
OSStatus status = SecTrustCreateWithCertificates(certificateRef, policyRef, &trustRef);
NSAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates failed.");
SecTrustResultType trustResult;
status = SecTrustEvaluate(trustRef, &trustResult);
NSAssert(status == errSecSuccess, @"SecTrustEvaluate failed.");
SecKeyRef publicKey = SecTrustCopyPublicKey(trustRef); //The Result :)
NSAssert(publicKey != NULL, @"SecTrustCopyPublicKey failed.");
if (certificateRef) CFRelease(certificateRef);
if (policyRef) CFRelease(policyRef);
if (trustRef) CFRelease(trustRef);
PS:为什么苹果这么难?静态链接OpenSSL很容易,但随后会出现各种出口法规和其他问题。
答案 0 :(得分:0)
问题显然是“证书”的来源,实际上并不比the key wrapped in some DER tags多。
由于这篇http://blog.wingsofhermes.org/?p=75博客文章中的黑魔法,我已成功地实现了我的大部分目标。
成功:
成功率较低:
我仍然不太清楚if语句的数组与循环和魔法数字的数量完全相同,但至少它是有效的,因为密钥总是来自同一个源,它不应该破坏除非他们改变了java安全提供程序......哦等等,这实际上有点可能......哦......至少它在Java 7标准中有点具体。
* p * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *