1

デルフィXe4. Win7Pro x64、Win8Ent x64、WinSrv2012 でテストします。

Const

CGuAdvapi32dll=WinApi.Windows.Advapi32;

CALG_MD2      = 32769;
CALG_MD4      = 32770;
CALG_MD5      = 32771;
CALG_SHA      = 32772;
CALG_SHA_1    = 32772; // CALG_SHA
CALG_SHA_256  = 32780;
CALG_SHA_384  = 32781;
CALG_SHA_512  = 32782;

CALG_DES      = 26113;
CALG_RC2      = 26114;
CALG_3DES     = 26115;
CALG_3DES_112 = 26121;
CALG_AES_128  = 26126;
CALG_AES_192  = 26127;
CALG_AES_256  = 26128;
CALG_AES      = 26128; // CALG_AES_256
CALG_RC4      = 26625;

PROV_RSA_AES = 24;        // The PROV_SSL provider type supports US AES crypto-algorithm
CRYPT_VERIFYCONTEXT = $F0000000;


{S} Function GuCryptAcquireContext(hProv: PULong; Container: LPCTSTR; Provider: LPCTSTR; ProvType: DWord; Flags: DWord): Bool; StdCall; External CGuAdvapi32dll Name 'CryptAcquireContextW';
{S} Function GuCryptReleaseContext(hProv: ULong; Flags: DWord): Bool; StdCall; External CGuAdvapi32dll Name 'CryptReleaseContext';
{S} Function GuCryptCreateHash(hProv: ULong; AlgId: ULong; hKey: ULong; Flags: DWord; Hash: PULong): Bool; StdCall; External CGuAdvapi32dll Name 'CryptCreateHash';
{S} Function GuCryptHashData(hHash: ULong; Data: PByte; DataLen: DWord; Flags: DWord): Bool; StdCall; External CGuAdvapi32dll Name 'CryptHashData';
{S} Function GuCryptDeriveKey(hProv: ULong; AlgId: ULong; hData: ULong; Flags: DWord; Key: PULong): Bool; StdCall; External CGuAdvapi32dll Name 'CryptDeriveKey';
{S} Function GuCryptDestroyHash(hHash: ULong): Bool; StdCall; External CGuAdvapi32dll Name 'CryptDestroyHash';
{S} Function GuCryptDestroyKey(hKey: ULong): Bool; StdCall; External CGuAdvapi32dll Name 'CryptDestroyKey';

...

Procedure Test64;
var   hProv, hKey, hHash: Ulong; key:string; CGuSoC:dword;
begin
  key:='my test password';CGuSoC:=sizeof(char);
  if not GuCryptAcquireContext(@hProv, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) then MessageBox(0, 'Not CAC', 0, 0);
   MessageBox(0, PChar(IntToStr(hprov)), 0, 0); // < --- 1 check !
  if not GuCryptCreateHash(hProv, CALG_MD2{MD5, SHA}, 0, 0, @hHash) then MessageBox(0, 'Not CCH', 0, 0);
  if not GuCryptHashData(hHash, @key[1], Length(key)*CGuSoC, 0) then MessageBox(0, 'Not CHD', 0, 0);
  if not GuCryptDeriveKey(hProv, CALG_RC4{RC2, AES}, hHash, 0, @hKey) then MessageBox(0, 'Not CDK', 0, 0);
  if not GuCryptDestroyHash(hHash) then MessageBox(0, 'Not CDH', 0, 0);
   MessageBox(0, PChar(IntToStr(hprov)), 0, 0); // < --- 2 check !
  if not GuCryptDestroyKey(hKey) then MessageBox(0, 'Not CDK', 0, 0);
  if hProv=0 then MessageBox(0, 'hProv=0!', 0, 0) else if not GuCryptReleaseContext(hProv, 0) then MessageBox(0, 'Not CRC', 0, 0);
end;

Q: ターゲット プラットフォーム「32 ビット ウィンドウ」でコンパイルします。すべて問題ありません。チェック文字列 1 と 2 では、大きな数値 ID が表示されます。882345。

ターゲット プラットフォーム「64 ビット Windows」でコンパイルし、正常に動作しますが、チェック 2 で「0」を示します (チェック 1 = OK、大きな数値)。なんで?

ps hProv 変数の型を ULong64 に変更します (proc.Test64 変数および GuCryptAcquireContext 定義内) が、結果はありません。

下手な英語でごめんなさい。

4

1 に答える 1

7

ここでの根本的な問題は、 を 32 ビット整数として変換したHCRYPTPROVことHCRYPTKEYですHCRYPTHASH。しかし、それらは実際にはポインタ サイズの整数です。として宣言する必要がありますNativeUInt

あなたの翻訳には他にも小さな問題があります。私のコメント:

  • 独自の型を発明しないでください。Windows ユニットで宣言されている型を使用してください。
  • Windows API 関数の名前を変更しないでください。関数がCryptEncryptWindows API で呼び出される場合は、その名前も使用する必要があります。そうしないと混乱を招きます。
  • 直訳しすぎないでください。varポインターではなくパラメーターを使用する準備をしてください。たとえば、最初のパラメーターはCryptAcquireContext、パラメーターとしてより適切varです。

私の最後の推奨事項は、API の既存の翻訳を使用することです。JEDI コードで見つかると思います。そうは言っても、私はJEDIプロジェクトと、それを発見可能にすることができないことに絶望しています.

于 2013-07-12T08:47:11.480 に答える