繁体   English   中英

来自iOS中X.509 ASN.1 RSA公钥的SecKeyRef

[英]SecKeyRef from X.509 ASN.1 RSA Public Key in iOS

我意识到我在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博客文章中,由于黑魔法,我已经成功地实现了我的大部分目标。

成功:

  • 从数据加载的密钥,而不是文件
  • java服务器成功读取的密钥加密(AES)密钥。

不太成功:

  • 不得不使用唯一标识符,但我重用它,所以不需要疯狂的命名方案。
  • 密钥暂时添加到钥匙串,但我在一次使用后将其删除,因此也可以解决。

我仍然不太清楚if语句的数组与循环和魔法数字的数量完全相同,但至少它是有效的,因为密钥总是来自同一个源,它不应该破坏,除非他们改变了java安全提供程序......哦等等,这实际上有点可能......哦......至少它在Java 7标准中有点具体。

*交叉手指* *希望没有任何打破*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM