1

私は C++ でこのコードを持っています (AnsiString は char* バッファのラッパーです):

BOOL HashIt(AnsiString &pw,BYTE *buf,BYTE &len)
{
   HCRYPTPROV cp;
   CryptAcquireContext(&cp,NULL,NULL,PROV_RSA_AES,CRYPT_VERIFYCONTEXT);

   HCRYPTHASH ch;
   CryptCreateHash(cp,CALG_MD5,0,0,&ch);

   CryptHashData(ch,(BYTE*)pw.c_str(),pw.Length(),0);

   HCRYPTKEY kc;
   CryptDeriveKey(cp,CALG_3DES,ch,CRYPT_EXPORTABLE,&kc);
   CryptExportKey(kc,NULL,PLAINTEXTKEYBLOB,0,buf,&dwLen);

   len = (BYTE) dwLen;
}

これまでのところ、これを .NET に変換しています。

    public static byte[] HashItB(string text)
    {
        byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(text);
        System.Security.Cryptography.MD5CryptoServiceProvider sp = new System.Security.Cryptography.MD5CryptoServiceProvider();

        byte[] hashBytes = sp.ComputeHash(textBytes);
        System.Security.Cryptography.PasswordDeriveBytes pdb = new System.Security.Cryptography.PasswordDeriveBytes(hashBytes, new byte[0]);
        hashBytes = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, hashBytes);

        // Need to export key as plain text blob here, CryptExportKey

        return (hashBytes);
    }

上記のコードが正しいと仮定すると、最後のステップは CryptExportKey 関数を .NET に変換することです。誰かが関数またはサンプルを教えてくれますか? C++ メソッドを変更できず、レガシ アプリと一致する .NET コードが必要です。または、.NET メソッドをあきらめて、C++ DLL を作成してそれを呼び出す必要がありますか (私の小さなアプリで別の DLL を出荷するための余分なサイズのため、それについては夢中ではありません)、またはすべての暗号関数をピンボークする必要がありますか?

4

3 に答える 3

3

.NETメソッドPasswordDeriveBytes.CryptDeriveKey()は、Win32 CryptoAPIメソッドを使用してパスワードをハッシュし、呼び出しCryptDeriveKeyて、最後に.NETを呼び出してキーをエクスポートするのと同じCryptExportKeyです。

C++コードは次と同等です。

byte[] textBytes = System.Text.Encoding.Default.GetBytes(text); // Default is the ANSI-code-page
System.Security.Cryptography.PasswordDeriveBytes pdb = new System.Security.Cryptography.PasswordDeriveBytes(textBytes, new byte[0]);
byte[] hashBytes = pdb.CryptDeriveKey("TripleDES", "MD5", 0, new byte[8]);

ただし、.NETコードは、エクスポートされたキー(PLAINTEXTKEYBLOB-header)から一部のヘッダーデータを削除します。192ビットの3DESキーの場合、これは"08 02 00 00 03 66 00 00 18 00 00 00"です。必要に応じて、.NETコードの前に追加することができます。

于 2012-04-18T05:51:35.923 に答える
1

PasswordDeriveBytes.CryptDeriveKey メソッドは既に派生キーを返しているため、C++ コードのようにキーをエクスポートする必要はありません。

于 2012-04-18T05:28:38.657 に答える
1

助けてくれてありがとう、そして誰かが後でこの投稿を読む必要がある場合に備えて、これが私が最終的に得たものです. バイト配列の構築の方が優れていると確信していますが、私の場合、このコードは高速である必要はないので、読みやすいものを使用しました。

    public static byte[] HashIt(string text)
    {
        byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(text);
        System.Security.Cryptography.PasswordDeriveBytes pdb = new System.Security.Cryptography.PasswordDeriveBytes(textBytes, new byte[0]);
        byte[] hashBytes = pdb.CryptDeriveKey("TripleDES", "MD5", 0, new byte[8]);
        byte[] head = new byte[] { 0x08,0x02, 0x00, 0x00, 0x03, 0x66, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 };
        byte[] hashBytesWithHead = new byte[hashBytes.Length + head.Length];
        head.CopyTo(hashBytesWithHead,0);
        hashBytes.CopyTo(hashBytesWithHead,head.Length);
        return (hashBytesWithHead);
    }
于 2012-04-18T15:41:12.150 に答える