【问题标题】:How to make a valid p12 file to be correctly imported by SecPKCS12Import如何使 SecPKCS12Import 正确导入有效的 p12 文件
【发布时间】:2012-04-19 00:40:24
【问题描述】:

我已经解决了我之前将 XML RSA 私钥转换为 PEM 文件的问题,但我遇到了另一个问题,即在导入 P12 私钥时我得到空数据。以下是我的步骤:

  1. 将 PEM 文件转换为 P12 文件

    openssl> pkcs12 -export -in rsa.pem -inkey rsa.pem -out rsa.p12 -nocerts
    
  2. 读取P12文件到iOS项目

    NSString *path = [[NSBundle bundleForClass:[self class]]    
                        pathForResource:@"MyPrivateKey" ofType:@"p12"];
    NSData *p12data = [NSData dataWithContentsOfFile:path];
    if (![self getPrivateKeyRef]) 
        RSAPrivateKey = getPrivateKeywithRawKey(p12data);
    
  3. 导入 P12 私钥

    SecKeyRef getPrivateKeywithRawKey(NSData *pfxkeydata)
    { 
        NSMutableDictionary * options = [[[NSMutableDictionary alloc] init] autorelease];
    
        // Set the public key query dictionary
        //change to your .pfx  password here 
        [options setObject:@"MyPassword" forKey:(id)kSecImportExportPassphrase];
    
        CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    
        OSStatus securityError = SecPKCS12Import((CFDataRef) pfxkeydata,
                                                 (CFDictionaryRef)options, &items);
    
        CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
        SecIdentityRef identityApp =
        (SecIdentityRef)CFDictionaryGetValue(identityDict,
                                             kSecImportItemIdentity);
        //NSLog(@"%@", securityError);
    
        assert(securityError == noErr);
        SecKeyRef privateKeyRef;
        SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
    
        return privateKeyRef;
    
    }
    

以为没有错误(OSStatus 值为 0),但 items 数组没有得到任何身份数据。我想知道我是否由于错误的 OpenSSl 使用而没有得到正确的 p12 文件格式。有人成功导入p12文件吗?纠结这个问题好几天了,如果你有线索,请给我建议,谢谢!

休伯特

【问题讨论】:

  • 关于 OpenSSL 的使用:1) 输入密钥肯定与您的输入证书不同 2) 文档说-nocerts 将在输出中不创建证书;你试过没有它吗?

标签: ios openssl rsa pkcs#12


【解决方案1】:

我从网上得到了一些提示,以下是获取 iOS 可接受的 p12 密钥和认证文件的步骤:

  1. 将 XML 转换为 PEM
    Shell> 编译 XMLSpec2PEM.java
    外壳> XMLSpec2PEM rsa.xml
    将输出结果保存到 rsa.pem
    (借用here

  2. 将 PEM 转换为 RSA 私钥
    OpenSSL> rsa -in rsa.pem -out rsaPrivate.key

  3. 生成认证请求
    OpenSSL> req -new -key rsaPrivate.key -out rsaCertReq.crt
    (输入一些基本的认证数据)

  4. 对请求进行签名认证
    OpenSSL> x509 -req -days 3650 -in rsaCertReq.crt -signkey rsaPrivate.key -out rsaCert.crt

  5. 将认证文件格式转换为 DER(iOS 可接受的格式)
    OpenSSL> x509 -outform der -in rsaCert.crt -out rsaCert.der

  6. 生成 PKCS12 私钥(iOS 可接受的格式)
    OpenSSL> pkcs12 -export -out rsaPrivate.pfx -inkey rsaPrivate.key -in rsaCert.crt

无需进一步步骤,步骤 5 和 6 中生成的文件现在可以在 iOS 中使用!

OpenSSL说明参考:
http://blogs.yaclife.com/?tag=ios%E3%80%80seckeyref%E3%80%80raw%E3%80%80key%E3%80%80rsa%E3%80%803des

http://devsec.org/info/ssl-cert.html

【讨论】:

  • 感谢 Hubert 的反馈。这是将 XML 编码的私钥转换为内部表示的一种非常迂回的方法,但它应该是正确的,我不确定是否有更健壮的方法(当然,在 Objective C 中编写转换例程之外)。哦,你可能会在一段时间后接受自己的答案!
  • 我想答案是肯定的。我上面所做的只是使用openssl命令行工具将其转换为有效的密钥格式,因此可以使用openssl api完成操作。我没有这样做只是因为我只需要这样做一次。
  • 在我的例子中,第 2 步“将 PEM 转换为 RSA 私钥”产生了与输入文件完全相同的输出文件。尽管如此,按照所有步骤生成的 p12 文件正是我的 iOS 应用程序所需要的,找到这篇文章对我有很大帮助。
  • 经过数亿小时的搜索后,我发现了唯一一个真正有用的提示。谢谢您的帮助。我在 SecKeyGetBlockSize 和 SecKeyRawSign 中得到了一些 EXC_BAD_ACCESS,因为 pkcs12 密钥文件是在没有任何证书的情况下生成的。我不明白为什么一个如此重要的事情如此该死地难以实施,而为了安全问题显然应该促进它。
猜你喜欢
  • 2020-08-13
  • 2010-09-20
  • 2011-12-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多