Алгоритм шифрования Diffie-Hellman (RFC 4419, 4253(8))
видео с разъяснениямиSSH-2 использует алгоритм Diffie-Hellman как основной (и единственный) метод обмена ключами.
Алгоритм Диффи-Хеллмана работает следующим образом:
- Предположим, что двум абонентам (P1 и P2) требуется установить между собой безопасное соединение, для которого необходимо согласовать ключ шифрования.
- P1 и P2 принимают к использованию два больших целых числа a и b, причем 1 < a < b.
- P1 выбирает случайное число i и вычисляет I = ai mod b. P1 передает I абоненту P2.
- P2 выбирает случайное число j и вычисляет J = aj mod b. P2 передает J абоненту P1.
- P1 вычисляет k1 = Ji mod b.
- P2 вычисляет k2 = Ij mod b.
- Имеем k1 = k2 = ai*j mod b, следовательно, k1 и k2 являются секретными ключами, предназначенными для использования при передаче других данных.
Примечание:
В приведенных выше уравнениях "mod" означает остаток. Например, 12 mod 10 = 2. Два - это остаток от деления 12 на 10.
The Diffie-Hellman (DH) key exchange provides a shared secret that cannot be determined by either party alone. The key exchange is combined with a signature with the host key to provide host authentication. This key exchange method provides explicit server authentication as defined in Section 7.
Для передачи ключа выполняются следующие шаги:
где
C - клиент;
S - сервер;
p - большое целое число;
g is a generator for a subgroup of GF(p);
q is the order of the subgroup;
V_S - идентификационная строка сервера;
V_C - идентификационная строка клиента;
K_S - открытый ключ хоста сервера;
I_C is C's SSH_MSG_KEXINIT message
I_S is S's SSH_MSG_KEXINIT message that have been exchanged before this part begins.
1. C генерирует случайное число x (1 < x < q) и вычисляет e = g^x mod p. C отправляет e на S.
2. S генерирует случайное число y (0 < y < q) и вычисляет f = g^y mod p. S получает e. Он вычисляет K = e^y mod p, H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K) (эти элементы закодированы согласно их типам; см ниже) и ставит подпись s на H своим закрытым ключом хоста. S отправляет (K_S || f || s) на C. Операция подписания может вызвать вторую операцию хеширования.
3. C проверяет что K_S действительно является ключём хоста для S (используя сертификаты или локальную БД). C также может принять ключ без проверки; однако, такие действия делают протокол небезопасным против активных атак (но сейчас они часто используются из практических соображений во многих окружениях). Далее C вычисляет K = f^x mod p, H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K) и проверяет подпись s на H.
Значения e или f которые не находятся в диапазоне [1, p-1] не должны быть отправлены или приняты любой из сторон. Если это условие будет нарушено, то обмен ключом закончится неудачей.