0

デルフィXe4. 関数 Win CryptoAPI - CryptEncrypt と CryptDecrypt を使用します。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa379924(v=vs.85).aspx (Enc) http://msdn.microsoft.com/en-us/library/windows /desktop/aa379913(v=vs.85).aspx (DeCr)

すべてが正常に機能し、文字列を暗号化および復号化します。しかし、すべての例で、オプション「HCRYPTHASH hHash」が使用されておらず、0 であることがわかります。また、ハッシュを発行した暗号化された文字列以上のものを暗号化する必要があります (個別に計算されず、CryptEncrypt(hProv, Hash , ...)で取得します)。 . そして復号化 - ソース文字列のハッシュを取得します。

実装方法がわかりません。

誰かが Delphi で例を示してくれるとありがたいです。

ps 更新削除*

4

1 に答える 1

4

1回のパスでプレーンテキストデータを暗号化およびハッシュしようとしていると思いますか? はいの場合、最初に Hash オブジェクトを作成し、そのハンドルを CryptEncrypt API に渡す必要があります。次に、CryptGetHashParam を使用してハッシュを取得します。

これは疑似コードです (テストされていませんが、進め方がわかります):

procedure doSomeEncryption()
var
  HASHOBJ: HCRYPTHASH;
  hProv: HCRYPTPROV;
  bHash: tBytes;
  dwHashBytes: DWORD;
begin
  if not CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then
    raiseLastOsError;

  if not CryptCreateHash(hProv, CALG_SHA, 0, 0, @HASHOBJ) then
    raiseLastOsError;

  // Your encrypt stuff here
  CryptEncrypt(yourHKey, HASHOBJ, ...) // 

  setLength(bHash, 255);  // Allocate the buffer
  if CryptGetHashParam(HASHOBJ, HP_HASHVAL, @bHash[0], @dwHashBytes, 0) then
  begin
    setLength(bHash, dwHashBytes);  // bHash now contains the hash bytes
  end
  else
    setLength(bHash, 0);

  //  Release HASHOBJ
  CryptDestroyHash(HASHOBJ);

  //  Release Provider Context
  CryptReleaseContext(hProv, 0);

end;
  • 私の擬似コードでは、ほぼすべての Windows API と型 (Crypt API を含む) の変換が含まれているため、 Jedi API プロジェクト (JWA)に依存しています。プロジェクトに含めることができます。
  • 疑似コードには、API エラー処理の改善が必要です。
  • bHash には、プレーンテキスト バージョンのデータのハッシュが含まれています。ハッシング (および暗号化) はバイト指向の操作であることに注意してください。つまり、文字列エンコーディングを「理解」していません。視覚的には、UTF16、UTF8、および ASCII でエンコードされた同じ文字列値は、異なるバイト表現を持つため、異なるハッシュ値になります。ハッシュ/暗号化するときは、エンコーディングに注意してください。

ところで、この動作は MSDN の CryptEncrypt API について文書化されています

hHash [入力] ハッシュ オブジェクトへのハンドル。データのハッシュ化と暗号化を同時に行う場合は、ハッシュ オブジェクトへのハンドルを hHash パラメータで渡すことができます。ハッシュ値は、渡されたプレーンテキストで更新されます。このオプションは、署名付きおよび暗号化されたテキストを生成する場合に役立ちます。CryptEncrypt を呼び出す前に、アプリケーションは CryptCreateHash 関数を呼び出して、ハッシュ オブジェクトへのハンドルを取得する必要があります。暗号化が完了したら、CryptGetHashParam 関数を使用してハッシュ値を取得するか、CryptSignHash 関数を使用してハッシュに署名することができます。ハッシュを実行しない場合、このパラメーターは NULL にする必要があります。

アップデート

暗号化後 H1 は、暗号化前のデータのハッシュになります。つまり、H1=HASH('aaa')

復号化後、H2 は復号化されたデータのハッシュ (平文値) になります。

したがって、復号化が成功した場合、H2 は HASH('aaa') と等しくなります。つまり、H1 = H2 です。

H1 & H2 の目的は、データの整合性をチェックすることです。通常、復号化関数は、復号化が成功したかどうかを通知しません。間違ったパスワードでデータを復号化しようとすると、ガベージ バイトが返されます。問題があります-復号化が成功したかどうかを知る方法は? これを行う 1 つの方法は、入力と出力でデータのハッシュを使用することです。それらが一致する場合、復号化は成功しています。ハッシュが異なる場合は、パスワードが間違っているなどの理由で、おそらく復号化が暗黙のうちに失敗した可能性があります。CryptEncrypt/CryptDecrypt は、これらのハッシュを個別にハッシュする代わりに、1 回の操作で取得する便利な方法を提供します。

于 2013-05-06T13:52:29.273 に答える