iOS:使用证书和签名验证文件 - 公共密钥错误,验证失败 [英] iOS: Verifying a File With a Certificate and Signature - Public Key is Wrong, Verification Fails
问题描述
我迄今为止所尝试的:
//加载所有文件
NSData * fileData = [NSData dataWithContentsOfFile:(...)];
NSData * signatureData = [NSData dataWithContentsOfFile:(...)];
NSData * certificateData = [NSData dataWithContentsOfFile:(...)];
SecCertificateRef certificate = SecCertificateCreateWithData(NULL,CFBridgingRetain(certificateData)); //加载证书
证书加载正常。可以使用
CFStringRef certificateDescription = SecCertificateCopySubjectSummary(certificate);
哪些工作。
由于在iOS上似乎没有方法直接复制公钥,所以我首先创建一个信任。
SecTrustRef信任
OSStatus statusTrust = SecTrustCreateWithCertificates(certificate,secPolicy,& trust);
SecTrustResultType resultType;
OSStatus statusTrustEval = SecTrustEvaluate(trust,& resultType);
这一切都适用于errSecSuccess结果。
现在我尝试获取公钥。
SecKeyRef publicKey;
publicKey = SecTrustCopyPublicKey(trust);
size_t keysize = SecKeyGetBlockSize(publicKey);
但是publicKey的内容
NSData * keyData = [NSData dataWithBytes:publicKey length:keysize];
与打开.cer文件时看到的公钥不同。所以这是第一个问题。
然后我尝试验证签名,即使我知道公钥是错误的。填充是正确的。
OSStatus verficationResult = SecKeyRawVerify(publicKey,kSecPaddingPKCS1,[fileData bytes],[fileData length],[signatureData bytes],[signatureData length]);
这个操作失败,OSStatus为-9809(操作无法完成)。我希望它是-25293 errSecAuthFailed。
我做错了什么?
我在 Apple Dev Forums 的提示帮助下解决了这个问题。 >
该问题与钥匙串无关。但是我将错误的参数传递给验证功能。它需要数据的摘要(hash),而不是数据直接。
NSData * fileData = [NSData dataWithContentsOfFile :(。 ..)];
NSData * signatureData = [NSData dataWithContentsOfFile:(...)];
NSData * certificateData = [NSData dataWithContentsOfFile:(...)];
SecCertificateRef certificateFromFile = SecCertificateCreateWithData(NULL,(__bridge CFDataRef)certificateData); //加载证书
SecPolicyRef secPolicy = SecPolicyCreateBasicX509();
SecTrustRef信任;
OSStatus statusTrust = SecTrustCreateWithCertificates(certificateFromFile,secPolicy,& trust);
SecTrustResultType resultType;
OSStatus statusTrustEval = SecTrustEvaluate(trust,& resultType);
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
uint8_t sha1HashDigest [CC_SHA1_DIGEST_LENGTH];
CC_SHA1([fileData bytes],[fileData length],sha1HashDigest);
OSStatus verficationResult = SecKeyRawVerify(publicKey,kSecPaddingPKCS1SHA1,sha1HashDigest,CC_SHA1_DIGEST_LENGTH,[signatureData bytes],[signatureData length]);
CFRelease(publicKey);
CFRelease(trust);
CFRelease(secPolicy);
CFRelease(certificateFromFile);
if(verficationResult == errSecSuccess)NSLog(@Verified);
I have three things: a file, a signature file, and a X509 certificate file .cer. The file has to be verified using the public key in the certificate and the signature file. I want to do it using Security.h/CommonCrypto.
What I tried so far:
// load all the files
NSData* fileData = [NSData dataWithContentsOfFile:(...)];
NSData* signatureData = [NSData dataWithContentsOfFile:(...)];
NSData* certificateData = [NSData dataWithContentsOfFile:(...)];
SecCertificateRef certificate = SecCertificateCreateWithData(NULL, CFBridgingRetain(certificateData)); // load the certificate
The certificate loads just fine. It's name can be checked using
CFStringRef certificateDescription = SecCertificateCopySubjectSummary(certificate);
which works. As there seems to be no method on iOS to copy the public key directly, I first create a trust.
SecTrustRef trust;
OSStatus statusTrust = SecTrustCreateWithCertificates( certificate, secPolicy, &trust);
SecTrustResultType resultType;
OSStatus statusTrustEval = SecTrustEvaluate(trust, &resultType);
This all works fine with a errSecSuccess result.
Now I try to get the public key.
SecKeyRef publicKey;
publicKey = SecTrustCopyPublicKey(trust);
size_t keysize = SecKeyGetBlockSize(publicKey);
But the content of publicKey
NSData* keyData = [NSData dataWithBytes:publicKey length:keysize];
is not the same as the public key I see when opening the .cer file. So this is problem number one.
Then I try to verify the signature, even though I know the public key is wrong. The padding is correct.
OSStatus verficationResult = SecKeyRawVerify(publicKey, kSecPaddingPKCS1, [fileData bytes], [fileData length], [signatureData bytes], [signatureData length]);
This fails with a OSStatus of -9809 (The operation couldn’t be completed). I expect it to be –25293 errSecAuthFailed.
Am I doing something fundamentally wrong?
I solved the problem with the help of a hint from Apple Dev Forums.
The problem had nothing to do with the keychain. But I passed the wrong parameters to the verification function. It needs a digest (hash) of the data, not the data directly.
NSData* fileData = [NSData dataWithContentsOfFile:(...)];
NSData* signatureData = [NSData dataWithContentsOfFile:(...)];
NSData* certificateData = [NSData dataWithContentsOfFile:(...)];
SecCertificateRef certificateFromFile = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData); // load the certificate
SecPolicyRef secPolicy = SecPolicyCreateBasicX509();
SecTrustRef trust;
OSStatus statusTrust = SecTrustCreateWithCertificates( certificateFromFile, secPolicy, &trust);
SecTrustResultType resultType;
OSStatus statusTrustEval = SecTrustEvaluate(trust, &resultType);
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
uint8_t sha1HashDigest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([fileData bytes], [fileData length], sha1HashDigest);
OSStatus verficationResult = SecKeyRawVerify(publicKey, kSecPaddingPKCS1SHA1, sha1HashDigest, CC_SHA1_DIGEST_LENGTH, [signatureData bytes], [signatureData length]);
CFRelease(publicKey);
CFRelease(trust);
CFRelease(secPolicy);
CFRelease(certificateFromFile);
if (verficationResult == errSecSuccess) NSLog(@"Verified");
这篇关于iOS:使用证书和签名验证文件 - 公共密钥错误,验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!