4

ファイル、署名ファイル、X509証明書ファイル.cerの3つがあります。ファイルは、証明書の公開鍵と署名ファイルを使用して検証する必要があります。Security.h/CommonCryptoを使用して実行したいと思います。

私がこれまでに試したこと:

// 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

証明書は問題なくロードされます。名前は以下を使って確認できます

CFStringRef certificateDescription = SecCertificateCopySubjectSummary(certificate);

動作します。iOSには公開鍵を直接コピーする方法がないように思われるので、最初に信頼を作成します。

SecTrustRef trust;
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の場合に失敗します(操作を完了できませんでした)。–25293errSecAuthFailedになると思います。

私は根本的に間違ったことをしていますか?

4

2 に答える 2

10

私はAppleDevForumsからのヒントの助けを借りて問題を解決しました。

問題はキーチェーンとは何の関係もありませんでした。しかし、検証関数に間違ったパラメーターを渡しました。データを直接ではなく、データのダイジェスト(ハッシュ)が必要です。

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");
于 2013-03-20T14:35:10.170 に答える
0

問題は、重要なデータを取得しようとしているときです。

SecKeyRef publicKey;
publicKey = SecTrustCopyPublicKey(trust);
size_t keysize = SecKeyGetBlockSize(publicKey);
But the content of publicKey

NSData* keyData = [NSData dataWithBytes:publicKey length:keysize];

それは公開鍵ではありません。これは、SecKeyRefデータ構造の最初の「X」バイトです(「X」は公開鍵のサイズです)。それは特に有用なことではありません。

SecKeyRef残念ながら、私はからに直接行く方法を知りませんNSData。あなたがしなければならないことは、SecKeyRefキーチェーン( )に入れて、それを(セットで)SecItemAddフェッチすることです。フェッチして戻すと、公開鍵がとして使用されます。SecItemCopyMatchingkSecReturnDataNSData

(AppleがなぜSecurity.frameworkを非常に複雑に使用できるようにするのかわかりません...)

于 2013-03-15T20:20:09.050 に答える