SecKeyRawVerify 在 mac 上验证,但在 iOS 上失败并返回 -9809
SecKeyRawVerify verifies on mac but fails with -9809 on iOS
我需要对 mac 一些数据进行数字签名,然后在 iOS 上对其进行验证。因此,我使用开放式 ssl 以 DER 格式为 public 密钥生成了 RSA 密钥对和证书(尝试使用 SecKeyGeneratePair 生成,但随后更难将 Public 密钥导入 iOS 并且 SecKeyRawVerify 仍然没有使用相同的结果),并在 Mac 应用程序上签署我的数据。然后,如果我在 iOS 上验证此数据,验证失败并显示 -9809 错误代码,但如果在 mac 上执行相同的代码,则验证成功。
这是我的验证码:
NSString* certPath = [[NSBundle mainBundle] pathForResource: @"Public" ofType:@"der"];
NSData* certificateData = [NSData dataWithContentsOfFile: certPath];
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);
NSString* licensingPolicyString = @"ZKL3YXtqtFcIeWRqSekNuCmtu/nvy3ApsbJ+8xad6cO/E8smLHGfDrTQ3h/38d0IMJcUThsVMyX8qtqILmPeTnBpZgJetBjb8kAfuPznzxOrIcYd27/50ThWv6guLqZL7j1apnfRZHAdMiozvEYH62sma1Q9qTl+W7qxEAxWs2AXDTQcF7nGciEM6MEohs8u879VNIE1VcPW8ahMoe25wf8pvBvrzE0z0MR4UFE3ZSWIeeQsiaUPYFwHbfQAOifaw/qIisjL5Su6WURoaSupWTMdQh3ZNyqZuYJaT70u8S7NgF3BzG8uBiYOUYsf6UayvkABmF0UuMdcvhPQefyhuXsiYWxsb3dFeGNoYW5nZSI6dHJ1ZSwiYWxsb3dTaGFmZXIiOnRydWUsInBvbGljeSBuYW1lIjp0cnVlfQ==";
size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey);
NSData* messageData = [[NSData alloc] initWithBase64EncodedData:[licensingPolicyString dataUsingEncoding: NSUTF8StringEncoding] options:0];
NSData* signatureData = [messageData subdataWithRange:NSMakeRange(0, signedHashBytesSize)];
NSData* rawMessageData = [messageData subdataWithRange: NSMakeRange(signedHashBytesSize, messageData.length - signedHashBytesSize)];
uint8_t sha1HashDigest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([rawMessageData bytes], (CC_LONG)[rawMessageData 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");
Mac和iOS的数字签名验证有什么不同吗?我没能在 Apple 的文档中找到任何相关信息。
在对 sign/verify 进行一些试验后,我发现将填充协议从 kSecPaddingPKCS1SHA1 更改为 SecKeyRawVerify/SecKeyRawSign 到 kSecPaddingPKCS1 可以解决我的问题。不知道为什么它不能与 kSecPaddingPKCS1SHA1 一起使用,Apple 的文档中没有描述弃用。此外,我没有在不同于 8.3 的 iOS 上尝试此代码,所以可能是 iOs8.3 问题。
我需要对 mac 一些数据进行数字签名,然后在 iOS 上对其进行验证。因此,我使用开放式 ssl 以 DER 格式为 public 密钥生成了 RSA 密钥对和证书(尝试使用 SecKeyGeneratePair 生成,但随后更难将 Public 密钥导入 iOS 并且 SecKeyRawVerify 仍然没有使用相同的结果),并在 Mac 应用程序上签署我的数据。然后,如果我在 iOS 上验证此数据,验证失败并显示 -9809 错误代码,但如果在 mac 上执行相同的代码,则验证成功。
这是我的验证码:
NSString* certPath = [[NSBundle mainBundle] pathForResource: @"Public" ofType:@"der"];
NSData* certificateData = [NSData dataWithContentsOfFile: certPath];
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);
NSString* licensingPolicyString = @"ZKL3YXtqtFcIeWRqSekNuCmtu/nvy3ApsbJ+8xad6cO/E8smLHGfDrTQ3h/38d0IMJcUThsVMyX8qtqILmPeTnBpZgJetBjb8kAfuPznzxOrIcYd27/50ThWv6guLqZL7j1apnfRZHAdMiozvEYH62sma1Q9qTl+W7qxEAxWs2AXDTQcF7nGciEM6MEohs8u879VNIE1VcPW8ahMoe25wf8pvBvrzE0z0MR4UFE3ZSWIeeQsiaUPYFwHbfQAOifaw/qIisjL5Su6WURoaSupWTMdQh3ZNyqZuYJaT70u8S7NgF3BzG8uBiYOUYsf6UayvkABmF0UuMdcvhPQefyhuXsiYWxsb3dFeGNoYW5nZSI6dHJ1ZSwiYWxsb3dTaGFmZXIiOnRydWUsInBvbGljeSBuYW1lIjp0cnVlfQ==";
size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey);
NSData* messageData = [[NSData alloc] initWithBase64EncodedData:[licensingPolicyString dataUsingEncoding: NSUTF8StringEncoding] options:0];
NSData* signatureData = [messageData subdataWithRange:NSMakeRange(0, signedHashBytesSize)];
NSData* rawMessageData = [messageData subdataWithRange: NSMakeRange(signedHashBytesSize, messageData.length - signedHashBytesSize)];
uint8_t sha1HashDigest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1([rawMessageData bytes], (CC_LONG)[rawMessageData 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");
Mac和iOS的数字签名验证有什么不同吗?我没能在 Apple 的文档中找到任何相关信息。
在对 sign/verify 进行一些试验后,我发现将填充协议从 kSecPaddingPKCS1SHA1 更改为 SecKeyRawVerify/SecKeyRawSign 到 kSecPaddingPKCS1 可以解决我的问题。不知道为什么它不能与 kSecPaddingPKCS1SHA1 一起使用,Apple 的文档中没有描述弃用。此外,我没有在不同于 8.3 的 iOS 上尝试此代码,所以可能是 iOs8.3 问题。