0

CryptoAPI (CAPI) を使用して Diffie Hellman Key Exchange を実行しようとしています。MSDN ドキュメントを使用しています。

        // Step 0) Acquire context
        if (!CAPI.CryptAcquireContext(ref this._cryptographicProvider, null, null, CAPI.PROV_DSS_DH, CAPI.CRYPT_VERIFYCONTEXT))
            HandleWin32Error("Unable to acquire cryptographic context");

        // Setp 1) Generate private key
        if (!CAPI.CryptGenKey(this._cryptographicProvider, CAPI.CALG_DH_EPHEM, DHKEYSIZE << 16 | CAPI.CRYPT_EXPORTABLE | CAPI.CRYPT_PREGEN, ref this._privateKeyPointer))
            HandleWin32Error("Unable to generate private cryptographic key");

        uint gSize = 0;
        CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, null, ref gSize, (uint)0);

        byte[] g = new byte[gSize];
        var res = CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, g, ref gSize, (uint)0);

最初の呼び出し CryptGetKeyParam は完全に機能します。つまり、g のサイズを 64 として正常に返します。

次に、コードは最後の行で失敗します。これは、res = true を使用して (その例の場合のように) g バッファーに何も返さないか、次の呼び出しを使用すると AccessViolationException が発生します。

var res = CAPI.CryptGetKeyParam(this._privateKeyPointer, CAPI.KP_G, ref g, ref gSize, (uint)0);

はい、P\Invoke メソッドをオーバーロードしました。

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, ref byte[] pbData, ref uint pdwDataLen, uint dwFlags);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, byte[] pbData, ref uint pdwDataLen, uint dwFlags);

これに関する考え/アイデアはありますか?

*興味深いことに、私は完全な Diffie Hellman Key Exchange を機能させることができました。つまり、2 つの当事者間で同じ秘密 (s1) の合意に成功しました。ただし、これは事前定義された P および G パラメータを使用したものです。導出されたシークレットがすべてのキー交換で同じであり、X が一貫していたことを意味するため、何かが正しくないように思われたため、コードを作り直しています。(つまり、Bob と Alice は毎回 s1 に同意した!?) - ここでも、KP_KEYLEN を使用するときにセッション キーのサイズを特定できなかったため、CryptGetKeyParam で問題が発生しました?! *

4

1 に答える 1

1

あはは!

これは、コンテキスト フラグとオーバーロードされたメソッドの組み合わせでした...今すぐ動作します!

P と G が事前定義されていない場合は、CRYPT_PREGEN フラグを設定しないでください...そして、2 つのオーバーロードされたメソッドのうちの 1 つだけが必要でした (これ):

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptGetKeyParam(IntPtr hKey, uint dwParam, byte[] pbData, ref uint pdwDataLen, uint dwFlags);
于 2010-08-03T09:36:56.347 に答える