SecCertificateCreateWithData总是返回null

5

我目前正在从以下帖子中工作。下面是代码:

    SecCertificateRef   certs    = NULL;
    SecPolicyRef        policy  = NULL;

    NSString *publicKeyString = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeJ8N8fuGShAJnniDg4yuRrxrG61ZF2T24eXSEH87jCJmLbc+MV70AgP/LC8btzSU4FFP56lBmDcmW+Prupf5gO1RXhjPIlET73t5Ny1I3ze+xaShAA9qB0c9dNb26NxVd95wCHNmQhon9qBFmTVZb0CdgscxYcDuLOGskDnATrwIDAQAB";
    NSData *publicKeyStringData = [[NSData alloc] initWithBase64EncodedString:publicKeyString options:0];


    certs = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef) publicKeyStringData);

根据这篇文章,如果certs变量是空的,那么数据的格式不正确。我检查了上述公钥,确实它是base64编码的,所以我不知道为什么certs会为空?


你检查过证书数据是否有效吗? - Aris
你有解决方案吗?我也遇到了同样的问题。 - RMDeveloper
4个回答

21
证书可以有这些扩展名:.CER、.CRT、.DER、.PEM。它可以用两种方式编码:DER 和 PEM。这个苹果方法只接受 DER 编码。
如果您的扩展名是 .CER 或 .CRT,则需要查找它是否编码为 DER 或 PEM。(如果有 .PEM 或 .DER 扩展名就很清楚了。)
要检查当前编码,请更改扩展名为 DER 并尝试读取它:
  1. 重命名文件(certificate.crt -> certificate.der)
  2. 在终端中:openssl x509 -in certificate.der -inform der -text -noout
如果出现错误,很可能是 PEM 编码的证书,您需要将其转换为 DER 编码:
  1. 改回 crt(certificate.der -> certificate.crt)
  2. 在终端中:openssl x509 -in certificate.crt -outform der -out certificate.der
// 来源:https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them

谢谢,讲解得很清楚,解决了我的问题。 - Eric Yuan

5
如果您正在检查iOS版本10或更高版本,则SecCertificateCreateWithData将返回nil
在iOS10中,安全框架有所改变。要么“SecCertificateCreateWithData”在iOS10中出现了问题,要么该方法变得更加严格。
看起来像是一个漏洞。
您可以在此处查看错误报告:https://openradar.appspot.com/28618141 还可以在此处阅读相关的gitHub帖子:https://github.com/lionheart/openradar-mirror/issues/16045 编辑:
从这里的线程中获取信息:为什么SecCertificateCreateWithData总是返回nil? 还应检查相同内容的文档:SecCertificateCreateWithData 引用:

SecCertificateCreateWithData返回nil的最常见原因是数据不是有效证书。常见问题是人们尝试传递PEM格式的证书,而SecCertificateCreateWithData需要DER格式。如果您使用文本编辑器打开证书,是否看到Base64?还是看到二进制结构?如果看到Base64,则需要将证书转换为二进制(DER)格式,然后再传递给SecCertificateCreateWithData。对于您在捆绑包中包括的单个证书,您可以使用Mac上的钥匙串访问进行预转换。


我刚在iOS 9设备上运行了代码,仍然得到一个NULL。 - user481610

0

来自文档

SecCertificateCreateWithData

从证书的DER表示中创建一个证书对象。

...

返回值

新创建的证书对象。当您完成使用它时,请调用CFRelease函数释放此对象。如果传递给数据参数的数据不是有效的DER编码X.509证书,则返回NULL。

因此,也许您正在尝试使用的NSData不是DER格式?


0

试一下,

  NSData *data = [[NSData alloc]initWithBase64EncodedString:publicKeyString options:NSDataBase64DecodingIgnoreUnknownCharacters];


certs = SecCertificateCreateWithData(kCFAllocatorMalloc, (__bridge CFDataRef)data);

你有基于Swift的解决方案吗,@Ketan Parmar? - Max
让我们来看一下这段 Swift 代码:let data = Data(base64Encoded: publicKeyString, options: .ignoreUnknownCharacters) if let data = data as? CFData? { var cert = SecCertificateCreateWithData(kCFAllocatorMalloc, data) } 我的问题是,无论如何 data 都是 nil,你有什么线索吗? - Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接