2

.NETで利用可能なMicrosoft暗号化プロバイダーを使用して、暗号化にOpenSSLを使用するコードを取得し、C#で記述している別のプログラムをうまく処理する方法を理解しようとしています。

もっと要点を言えば、私はC#プログラムにOpenSSLコードによって生成されたRSAメッセージ署名を検証させようとしています。署名を生成するコードは次のようになります。

// Code in C, using the OpenSSL RSA implementation

char msgToSign[] = "Hello World";     // the message to be signed
char signature[RSA_size(rsa)];        // buffer that will hold signature
int slen = 0;                         // will contain signature size

// rsa is an OpenSSL RSA context, that's loaded with the public/private key pair

memset(signature, 0, sizeof(signature));

RSA_sign(NID_sha1
      , (unsigned char*)msgToSign
      , strlen(msgToSign)
      , signature
      , &slen
      , rsa);

// now signature contains the message signature
//  and can be verified using the RSA_verify counterpart
// .. I would like to verify the signature in C#

C#では、次のようにします。

  • 反対側の公開鍵をRSACryptoServiceProviderオブジェクトにインポートします
  • メッセージとその署名を受信します
  • 署名を確認してみてください

最初の2つの部分が機能しています(RSA暗号化テキストをC#コードからCのOpenSSLコードに送信し、正常に復号化できたため、公開鍵が正しく読み込まれていることを確認しました)

C#で署名を検証するために、RSACryptoServiceProviderのVerifySignatureメソッドを使用してみましたが、機能しませんでした。そしてインターネットを調べてみると、.NETがOpenSSLとは異なる方法で署名を生成していることを指摘する漠然とした情報しか見つかりませんでした。それで、誰かがこれを達成する方法を知っていますか?

編集

リクエストがあったので、これがC#側です。

byte[] receivedSignature;
// ....
// receivedSignature is set to the byte array generated by the OpenSSL side
//   I've verified this much is working correctly

// I use my utility to parse a PEM file and extract the other side's public key
//   also, verified to be working correctly - the public key is good.
RSACryptoServiceProvider rsa = MyPEMLoader.LoadFromFile("publicKey.pem");

string msgToVerify = "Hello World";
byte[] msgBytes = Encoding.ASCII.GetBytes(msg);  // other side uses ASCII, so do the same
bool verified = rsa.VerifyHash(msgBytes, "SHA1", receivedSignature);

// verfied is false.. verfification failed!
4

2 に答える 2

1

C#コードを表示すると役立つ場合があります。私はそれが次のようなものであるべきだと思います:

    string msg = ...;
    byte[] localData = Encoding.UTF8.GetBytes(msg);
    bool ok = rsa.VerifyHash(localData, "SHA1", receivedhash);

そしてもちろん、UTF-8の部分を推測しているだけです。ASCIIの場合もあります。

編集:これがMSDNページです。例はそれを異なっているように見えます、localDataは最初にハッシュされます。

hashedData = hash.ComputeHash(signedData);
return rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature);
于 2010-05-11T16:02:12.837 に答える
0

pem ユーティリティを削除する必要があります。これは必須ではありません。

 var cert = new X509Certificate2(HttpContext.Current.Request.MapPath("~/App_Data/PublicKey.pem"), "");
var rsaCryptoIPT = (RSACryptoServiceProvider)cert.PublicKey.Key;
var sha1 = new SHA1CryptoServiceProvider();
if (!rsaCryptoIPT.VerifyData(data, sha1, signature))
                throw new InvalidOperationException("Invalid signature from bank ");

これで問題が解決しない場合は、pem ファイル リーダー コードを投稿してください。

于 2011-06-05T12:59:25.083 に答える