4

SHA1ハッシュがあり、署名する必要があります。CryptSignHash()メソッドには、署名用のHCRYPTHASHハンドルが必要です。私はそれを作成し、実際のハッシュ値をすでに持っているので、それを設定します:

CryptCreateHash(cryptoProvider, CALG_SHA1, 0, 0, &hash);
CryptSetHashParam(hash, HP_HASHVAL, hashBytes, 0);

hashBytesは20バイトの配列です。

ただし、問題は、このHCRYPTHASHハンドルから生成された署名が正しくないことです。問題は、CAPIがhashBytes配列の20バイトすべてを実際に使用しているわけではないという事実にまでさかのぼります。何らかの理由で、SHA1はわずか4バイトであると考えられます。

これを確認するために、私はこの小さなプログラムを作成しました。

HCRYPTPROV cryptoProvider;
CryptAcquireContext(&cryptoProvider, NULL, NULL, PROV_RSA_FULL, 0);

HCRYPTHASH hash;
HCRYPTKEY keyForHash;
CryptCreateHash(cryptoProvider, CALG_SHA1, keyForHash, 0, &hash);

DWORD hashLength;
CryptGetHashParam(hash, HP_HASHSIZE, NULL, &hashLength, 0);
printf("hashLength: %d\n", hashLength);

そしてこれはhashLengthを出力します:4!

誰かが私が間違っていることや、SHA1が20バイト(160ビット)ではなく4バイト(32ビット)であるとMicrosoftCAPIが考える理由を説明できますか?

4

2 に答える 2

3

コードに小さなエラーがあります。それ以外の

DWORD hashLength;
CryptGetHashParam(hash, HP_HASHSIZE, NULL, &hashLength, 0);
printf("hashLength: %d\n", hashLength);

あなたが使用する必要があります

DWORD hashLength, hashSize;
hashLength = sizeof(DWORD)
CryptGetHashParam(hash, HP_HASHSIZE, (PBYTE)&hashSize, &hashLength, 0);
printf("hashSize: %d\n", hashSize);

その後、期待どおり 20 を受け取ります。

CryptSignHashafterの使用法CryptSetHashParamも機能する必要があります。http://msdn.microsoft.com/en-us/library/aa380270(VS.85).aspxCryptSetHashParamで関数の説明の最後にあるコメントを参照してください。署名の結果を取得するときと同じエラーが発生したと思います。関数http://msdn.microsoft.com/en-us/library/aa380280(VS.85).aspxの説明のコードとコードを比較してください。CryptGetHashParam(..., HP_HASHSIZE, ...)CryptSignHash

于 2010-06-08T19:34:51.013 に答える
1

そういう使い方はできないと思いますCryptCreateHashMSDNから:

「CryptCreateHash 関数は、データ ストリームのハッシュを開始します。」

言い換えれば、空以外の方法でハッシュコンテキストをインスタンス化することはできないようです(そして、入力データをハッシュすることによって)。

現在、どのようにハッシュを持っていますか - バイト配列ですか? もしそうなら、おそらくその配列に署名したいだけです。私はその仕事を検討するCryptSignMessageか、その可能性が高いと思います。CryptSignMessageWithKey

(私は推測していますが、あなたが見ていることは、ハッシュコンテキストが何らかの作業を行うまで出力ハッシュ長が設定されていないことによって説明されるかもしれません.)

于 2010-05-28T11:26:01.017 に答える