可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm currently working from the following post. Here is the code:
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);
Based on the post if the certs
variable is NULL then data was in an incorrect format. I checked the above public key and it is indeed base64, so I can't see why certs
would be NULL?
回答1:
If you are checking in iOS version 10 or greater, then SecCertificateCreateWithData
will return nil
.
something changed in the Security Framework in iOS10. Either "SecCertificateCreateWithData" is broken in iOS10 or the method has become more strict.
Looks like a bug.
You can see bug report at: https://openradar.appspot.com/28618141
Also read related gitHub post here: https://github.com/lionheart/openradar-mirror/issues/16045
Edit:
From the thread here: Why SecCertificateCreateWithData is always return nil?
Also check the documentation for the same here: SecCertificateCreateWithData
The most common reason for SecCertificateCreateWithData
to return nil
is that the data isn’t a valid certificate. A common problem is that folks try to pass in a PEM
format certificate, whereas SecCertificateCreateWithData
requires DER
. If you open the certificate with a text editor, do you see Base64? Or do you see binary goo? If you see Base64
, you’ll need to convert the certificate to binary (DER
) form before passing to to SecCertificateCreateWithData
. For a single certificate that you include in your bundle, you can just pre-convert it using Keychain Access on the Mac.
回答2:
Try,
NSData *data = [[NSData alloc]initWithBase64EncodedString:publicKeyString options:NSDataBase64DecodingIgnoreUnknownCharacters]; certs = SecCertificateCreateWithData(kCFAllocatorMalloc, (__bridge CFDataRef)data);
回答3:
From the documentation:
SecCertificateCreateWithData
Creates a certificate object from a DER representation of a certificate.
...
Return Value
The newly created certificate object. Call the CFRelease function to release this object when you are finished with it. Returns NULL if the data passed in the data parameter is not a valid DER-encoded X.509 certificate.
So, perhaps the NSData you're trying to use isn't in a DER format?
回答4:
If you have .CER or .CRT certificate you have to find out if it is encoded in DER or PEM format.
To check the current encoding, change the extension to DER and try to read it:
- Rename the file (certificate.crt -> certificate.der)
- In terminal: openssl x509 -in certificate.der -inform der -text -noout
If you see an error it is likely PEM encoded certificate and you need to change it to DER encoded:
- Rename back to crt (certificate.der -> certificate.crt)
- In terminal: openssl x509 -in certificate.crt -outform der -out certificate.der
// source: https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them