2016-06-29 11 views
0

В настоящее время я разрабатываю SSH-клиент, и необходимо, чтобы клиент мог обмениваться ключами с сервером через ECDH KEX (NIST-256, 384 и 521).Извлечь общий секрет из класса ECDiffieHellmanCng

Я сделал несколько (на самом деле много) исследований, нашел .NET класс ECDiffieHellmanCng и смог извлечь и импортировать открытый ключ сервера в класс.

Проблема в том, что я не могу извлечь общий секрет без его получения (ECDiffieHellmanCng.DeriveKeyMaterial(CngKey otherpartyPublicKey)).

Есть ли способ прямого доступа к общему секрета («k», как он называется в документах RFC)?

Here является страница 7 из RFC реализации ECDH и почему мне нужен общий секрет:

Обмен хэш-H вычисляется как хэш конкатенации следующее.

строка V_C, строка идентификации клиента (CR и LF исключены)

строка V_s, строка идентификации сервера (CR и LF исключены)

строку I_C, полезную нагрузку SSH_MSG_KEXINIT клиента

строки I_S , полезная нагрузка SSH_MSG_KEXINIT сервера

струнные K_S, общественный хост-сервера ключей

Строка Q_C, эфемерное открытый ключ строка октетов клиента

струнные Q_S, эфемерное ключ октет струнные сервера общественного

mpint K, общий секрет < - вот почему мне нужен чистый секретный перед любым выводом

Спасибо за любые решения или подсказки!

ответ

0

Даже после многих исследований я не мог найти способ сделать это, так что ответ отрицательный - вы не можете извлечь секрет.

Мое решение для большой картины заключалось в том, чтобы полностью отказаться от класса ECDiffieHellmanCng и вместо этого обернуть библиотеку OpenSSH на C#.

Надеюсь, это по крайней мере поможет кому-то еще с той же идеей.

1

Вам действительно не нужно k, тогда вам просто нужно вычислить H. Класс ECDiffieHellman позволяет это сделать.

byte[] prepend = Concat(V_C, V_S, I_C, I_S, K_S, Q_C, Q_S); 
byte[] exchangeHash = ecdh.DeriveKeyFromHash(otherPublic, new HashAlgorithmName("whatever your hash algorithm is"), prepend, null); 

Хотя это с помощью .NET 4.6.2 (в настоящее время в предварительном просмотре) API: DeriveKeyFromHash

Если вы находитесь на старой базы это все-таки возможно, но требует использования типа ECDiffieHellmanCng конкретно:

ecdhCng.SecretPrepend = prepend; 
ecdhCng.SecretAppend = null; 
ecdhCng.HashAlgorithm = new CngAlgorithm("whatever your hash algorithm is"); 
ecdhCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; 
byte[] exchangeHash = ecdhCng.DeriveKeyMaterial(otherPublic); 
+0

Спасибо за ответ. Я пробовал, но это не сработало для меня. Решение может представлять собой определенную комбинацию prepend и append, поскольку для того, чтобы генерировать ключ с ожидаемой длиной, иногда требуется больше одного вывода. Документация Майкрософт о их деривации, однако, отсутствовала, поэтому я не стал задумываться о ней слишком много. Я отвечу так, чтобы кто-то другой с этой проблемой мог дать ему еще одну попытку. :) – Oachkatzl