Я пытаюсь использовать 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 ?!
*