我意识到在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很容易,但是随后适用各种出口法规和其他问题。
问题显然出在“证书”的来源上,它实际上只不过是包裹在某些DER标签中的钥匙而已。
从正面来看,由于这篇http://blog.wingsofhermes.org/?p=75博客文章中的黑魔法,我成功地实现了我的大部分目标。
成功:
成功较少:
我仍然不太清楚if语句数组与循环和大量魔术数字混合的确切作用,但是至少它可以工作,并且由于密钥始终来自同一来源,因此除非它们更改了key,否则它不会中断。 Java安全提供程序...等等,这实际上很有可能...哦,好吧……至少它在Java 7标准中有些特定。
*交叉手指* *希望一切都不会中断*
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句