我必须使用存储在我的应用程序包中的证书中的公钥来验证从服务器收到的证书的签名。
我认为问题在于我使用证书中的签名的方式。我使用浏览器从证书中提取了签名,我将其用作字符串。我不确定这个字符串的格式是什么。(可能是普通的utf-8或SHA-1,但我不确定,我也不确定如何从服务器证书中提取签名。)
我使用以下代码,但它返回错误代码-9809。
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
id <NSURLAuthenticationChallengeSender> sender = challenge.sender;
NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
SecTrustRef trust = [protectionSpace serverTrust];
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);
NSData* serverCertificateData = (__bridge NSData*)SecCertificateCopyData(certificate);
const unsigned char *certificateDataBytes = (const unsigned char *)[serverCertificateData bytes];
X509 *certificateX509 = d2i_X509(NULL, &certificateDataBytes, [serverCertificateData length]);
NSString *issuerCN = CertificateGetIssuerCommonName(certificateX509);
if ([self shouldTrustProtectionSpace:protectionSpace]) {
NSString *organizationalUnit = CertificateGetOrganizationalUnit(certificateX509);
NSString* str = @"4C 22 0D 34 9F 6F 0B 40 EE A0 56 22 70 57 75 1A B3 AC 21 A3 E3 F0 F4 D4 B9 8E CD E2 55 EE 09 7F D7 83 3C 67 68 4B 08 AB B6 00 A8 BE CD A9 73 CB 45 43 5F 67 96 15 A4 F2 4B 2D 31 0E F8 40 66 02 02 1A 39 2B A9 D7 EE AD 6A E8 FB FB AC FB 00 5F 05 5E 77 C5 9D 45 55 6F 0B 64 5F E7 93 A3 AE 52 8A 8E 7E BD BB EE E8 06 98 42 F6 F5 36 DE 9B 06 3A C9 05 6B 60 2C 4F 0A 6D C3 65 12 E8 E1 9C 36 8D F6 93 79 D7 D6 92 C0 87 EB EC 96 14 F7 FB B6 53 AC 28 A6 9B 80 0B 01 60 CA 87 10 74 EA 68 C4 34 97 AD 29 50 6B E5 29 7C 59 84 83 FD D2 4A 59 16 BB E2 6D 3C D9 D1 1E C4 AF 44 0A 85 99 B3 29 27 3D 9C 60 D9 08 77 85 FA";
NSData* signatureData = [str dataUsingEncoding:NSUTF8StringEncoding];
//Load the bundled client certificate
NSString* certPath = [[NSBundle mainBundle] pathForResource:@"root_LA" ofType:@"cer"];
NSData* cerData = [[NSData alloc] initWithContentsOfFile:certPath];
CFDataRef certDataRef = (__bridge_retained CFDataRef)cerData;
SecCertificateRef cert = SecCertificateCreateWithData(NULL, certDataRef);
SecPolicyRef secPolicy = SecPolicyCreateBasicX509();
SecTrustRef trust;
SecTrustCreateWithCertificates( cert, secPolicy, &trust);
SecTrustResultType resultType;
SecTrustEvaluate(trust, &resultType);
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
uint8_t sha1HashDigest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([serverCertificateData bytes], [serverCertificateData length], sha1HashDigest);
OSStatus verficationResult = SecKeyRawVerify(publicKey, kSecPaddingPKCS1SHA1, sha1HashDigest, CC_SHA1_DIGEST_LENGTH, [signatureData bytes], [signatureData length]);
CFRelease(publicKey);
CFRelease(trust);
CFRelease(secPolicy);
if (verficationResult == errSecSuccess) NSLog(@"Verified");
// VerificationResult comes as -9809
}
else
{
[sender cancelAuthenticationChallenge:challenge];
[connection cancel];
[self handleCertifcateVildationFailureForCN:issuerCN];
}
}