Получение исключения при вызове CryptGetKeyParam - PullRequest
0 голосов
/ 03 августа 2010

Я пытаюсь использовать CryptoAPI (CAPI) для обмена ключами Диффи-Хеллмана. Я использую документацию 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, либо с 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);

Есть какие-нибудь мысли / идеи по этому поводу?

* Интересно, что мне удалось заставить работать полный обмен ключами Диффи-Хеллмана, то есть успешно согласовать один и тот же секрет (ы) между двумя сторонами. Но это с предопределенными параметрами P и G. Я переделываю код, потому что что-то кажется неправильным, поскольку производный секрет был одинаковым для каждого обмена ключами, подразумевая, что X был непротиворечивым. (то есть Боб и Алиса согласовывали s1 каждый раз !?) - Здесь у меня снова возникла проблема с CryptGetKeyParam, поскольку я не смог определить размер ключа сеанса при использовании KP_KEYLEN ?! *

1 Ответ

1 голос
/ 03 августа 2010

Ах, ха!

Это была комбинация контекстных флагов и перегруженного метода ... Работает сейчас!

Если P & G НЕ предопределено, не устанавливайте флаг CRYPT_PREGEN ... И нужен был только один из двух перегруженных методов (этот):

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