7

C#と.NetCFを使用してX.509証明書を検証しようとしています。私はCA証明書を持っています。正しく理解している場合は、このCA証明書の公開鍵を使用して、信頼できない証明書の署名を復号化する必要があります。これにより、信頼できない証明書の計算されたハッシュ値が得られるはずです。次に、証明書のハッシュを自分で計算し、2つの値が一致することを確認する必要があります。

私はこれで数日間遊んでいますが、それほど遠くはありません。X509CertificateクラスとRSACryptoServiceProviderクラスを使用しています。まず、X509Certificateクラスから公開鍵と署名を取得しようとしました。公開鍵は取得できましたが、署名は取得できませんでした。次に、証明書を構成するバイナリデータを解析して、署名(およびその他の必要なデータ)を取得できるようにしましたが、RSACryptoServiceProviderを使用して署名を復号化できませんでした。私はこのようなことを試みましたが、復号化しようとすると「不正なキー」という例外が発生し続けました。

RSAParameters rsaParams = new RSAParameters();
rsaParams.Exponent = exp;
rsaParams.Modulus = mod;
RSACryptoServiceProvider rsaServ = new RSACryptoServiceProvider();
rsaServ.ImportParameters(rsaParams);
byte[] decryptedSig = rsaServ.Decrypt(encryptedSig, false);

アドバイスをいただければ幸いです。

編集:私はより良いように見えるが奇妙な結果を返している何かを試しました。テストが少し簡単なため、ここではX509Certificate2クラスを使用していますが、後で.NetCF用にX509Certificateに切り替える必要があります。RSACryptoServiceProvider.VerifyDataが必要なものかもしれないと思います。次のコードを試しました。

X509Certificate2 cert = new X509Certificate2(certBytes);
X509Certificate2 certCA1 = new X509Certificate2(@"C:\certs\certCA1.cer");

byte[] encryptedSig = new byte[256];
Array.Copy(certBytes, certBytes.Length - 256, encryptedSig, 0, 256);

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certA1.PublicKey.Key;
bool good = rsa.VerifyData(cert.RawData, "1.3.14.3.2.26", encryptedSig);

私が言ったように、私は証明書のバイナリデータを手動でデコードして解釈することができるので、cert.RawDataは証明書の署名されたデータであり、最後の256バイトは暗号化された署名であると確信しています。文字列は、証明書から取得したハッシュアルゴリズムのOIDですが、100%正しいかどうかはわかりません。VerificationDataはfalseを返しますが、理由はまだわかりません。

考え?

4

3 に答える 3

3

これが私のコードです。

RSACryptoServiceProvider rsa = signingCertificate_GetPublicKey();
return rsa.VerifyData( SignedValue(), CryptoConfig.MapNameToOID( "SHA1" ), Signature() );

RSACryptoServiceProvider signingCertificate_GetPublicKey()
{
    RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();

    RSAParameters publicKeyParams = new RSAParameters();
    publicKeyParams.Modulus = GetPublicKeyModulus();
    publicKeyParams.Exponent = GetPublicKeyExponent();

    publicKey.ImportParameters( publicKeyParams );

    return publicKey;
}

byte[] GetPublicKeyExponent()
{
    // The value of the second TLV in your Public Key
}

byte[] GetPublicKeyModulus()
{
    // The value of the first TLV in your Public Key
}

byte[] SignedValue()
{
    // The first TLV in your Ceritificate
}

byte[] Signature()
{
    // The value of the third TLV in your Certificate
}

それがこの問題に取り組んでいる人の助けになることを願っています。

于 2010-12-13T16:44:33.273 に答える
1

WinCEは、Win32 MSCrypto.dllと互換性のあるものをサポートしていますか?はいの場合は、.NETX509Certificate2クラスとCodeplexのCLRセキュリティライブラリを確認してください。 コアOS暗号ライブラリの上にある.NETに役立つルーチンがたくさん含まれています。ソースをダウンロードして、.NetCF用にコンパイルされる方法を確認できます。

X509証明書をロードして検証するには、次のようにします(テストされていません)。

var cert = new X509Certificate2("mycert.cer");  
if (!cert.Verify())
{
    <fail>
}

X509Certificate2には、ディスク上のファイル、メモリ内のバイト配列、ローカル証明書ストアからのロードなど、さまざまなソースから構築するコンストラクターが12個近くあります。

証明書の署名に使用されるルートCAは、ローカルの証明書ストアにインストールする必要があります。証明書に信頼チェーン内の中間CAが含まれていない場合、それらの中間体もローカルマシン上にある必要があります。これは、ローカルマシンの信頼できる証明書ストアにあるルートCAまでです。

残念ながら、MSDNドキュメントからX509Certificate2が.NetCFで利用可能かどうかはわかりません。

于 2010-09-02T19:34:19.373 に答える
0

これはwin32で機能しますが、Compact Frameworkでも同じ問題に直面しています。X509Certificate2がないため、実際にはブロックされています。win32を使用すると次のことができます。

X509Certificate2 l__PublicKeyCertificate = new X509Certificate2("cert.cer");

RSACryptoServiceProvider l__rsaCspPublic = (RSACryptoServiceProvider)l__PublicKeyCertificate .PublicKey.Key;

//...

l__isVerified = l__rsaCspPublic.VerifyData(l__fileData, CryptoConfig.MapNameToOID("SHA1"), l__fileSignature);
于 2010-12-10T10:59:27.570 に答える