Обмен ключами, также известный как соглашение о ключах, основной функцией этого механизма является получение временных сеансовых ключей взаимодействующих сторон.
Под временным сеансовым ключом здесь можно понимать симметричный ключ шифрования, но его срок действия ограничен одной сеансовой ссылкой и не действителен в течение длительного времени.
Фактически, ранее мы проанализировали, что симметричные ключи, такие как RSA, также могут использоваться для шифрования и дешифрования. Итак, в реальном процессе связи, таком как TLS, зачем нам генерировать временные симметричные ключи?
Здесь есть две основные причины:
Обмен ключами на основе RSA основан на двух основных характеристиках асимметричных ключей:
В простом сценарии обмена ключами,Есть две основные роли,Клиент и сервер。
Клиент и сервер перед ведением обычного делового общения,Всегда сначала необходимо онлайн-ключ данных,Используется для шифрования и дешифрования бизнес-потоков.
Здесь мы согласны с тем, что сервер всегда является авторитетным, и его открытый ключ воспринимается всеми клиентами. Клиент является произвольным и не имеет требований к идентификации. Клиент всегда инициирует связь с сервером, а сервер всегда отвечает клиенту доверенными данными.
В системе RSA клиент всегда генерирует ключ.
Это связано с тем, что клиент всегда может получить открытый ключ сервера, сгенерировать клиентом случайный ключ, а затем расшифровать его сервером с использованием закрытого ключа, обеспечивая тем самым конфиденциальность случайного ключа.
Закрытый ключ всегда хранится на сервере и никогда не будет опубликован.
Это предпосылка для шифрования данных на основе RSA.
Это также основа для обмена ключами на основе RSA.
После того, как сервер использует закрытый ключ для расшифровки зашифрованного текста случайным ключом, по умолчанию он использует тот же случайный ключ, который используется клиентом.
Последующие данные бизнес-потока используют этот случайный ключ для передачи данных.
Клиент не может различить источник открытого ключа, что является предпосылкой того, что RSA может быть атакован посредником.
Клиент может использовать открытый ключ только для шифрования случайного ключа. Однако клиент не может определить, принадлежит ли открытый ключ реальному серверу или посреднику.
Как только клиент принимает открытый ключ посредника, это означает, что клиент по умолчанию использует посредника в качестве реального сервера.
Тогда процесс обмена ключами данных, который мы описали ранее, может быть полностью отслежен или даже подделан посредником.
После того как клиент сгенерирует случайный ключ и зашифрует его, все его сообщения будут отслеживаться посредником. Поскольку клиент использует открытый ключ посредника, даже если случайный ключ зашифрован, посредник все равно может полностью получить его простой текст.
Посредник также может запутать сервер.
Например, после использования вашего собственного закрытого ключа для расшифровки случайного ключа попробуйте использовать открытый ключ сервера для шифрования случайного ключа, а затем отправьте его на сервер.
В это время сервер фактически не может отличить, является ли человек, отправляющий данные, клиентом или посредником.
В процессе обмена ключами RSA посредник должен гарантировать:
Методом предотвращения атак «человек посередине» на самом деле является метод аутентификации по идентификатору, а в настоящее время основным методом является цифровая подпись.
в предыдущей статье«Серия медитаций с асимметричным ключом (3): открытый ключ, подпись и сертификат»Мы говорили о некоторой базовой логике сертификатов и аутентификации личности.。
В этом процессе обмена ключами RSA сертификаты также можно эффективно использовать для идентификации и аутентификации личности.
В процессе аутентификации сервера самым важным по-прежнему остается решение трех задач:
Я не буду здесь вдаваться в подробности.,Подробно описано в предыдущей статье.,Если вам интересно, вы можете прочитать это«Серия медитаций с асимметричным ключом (3): открытый ключ, подпись и сертификат»。
В предыдущем описании,Фактически мы сосредоточились только на описании использования клиентом открытых ключей для шифрования случайных ключей.,Затем сервер использует закрытый ключ для расшифровки случайного ключа.。Фактически, объединение«Серия медитаций на асимметричный ключ (2): разговоры о RSA и цифровых подписях»содержание в,Когда мы обмениваемся случайными ключами,Его также можно комбинировать с HMAC и другими методами для случайных ключей.,Убедитесь, что случайный ключ не подделан. Заинтересованные студенты здесь могут подумать об этом сами.
Ранее мы много говорили о RSA, но на самом деле RSA больше ориентирован на алгоритмы с асимметричным ключом, а его основная функция — собственно шифрование и дешифрование.
Протокол обмена ключами DH специально используется для генерации ключей переговоров.
RSA можно использовать для передачи информации, а DH больше подходит для согласования ключей.
Алгоритм DH решает проблему обмена ключами без прямой передачи ключа между двумя сторонами. Этот магический принцип обмена полностью поддерживается математической теорией.
Поскольку алгоритмы серии DH включают в себя относительно сложные математические операции рассуждения, мы не будем здесь вдаваться в подробные объяснения. Заинтересованные студенты могут прочитать соответствующие документы RFC.
Самый оригинальный алгоритм DH не может противостоять MIMT (атаке «Человек посередине»), поэтому он обычно должен сотрудничать с технологией подписи, которая не взаимодействует с технологией подписи, называется DH-ANON;
Тот, который взаимодействует с подписью RSA, называется DH-RSA;
Тот, который взаимодействует с подписью DSA, называется DH-DSA;
Тот, который взаимодействует с подписью ECDSA, называется DH-ECDSA;
В целом, протокол DH также боится атак «человек посередине». Вообще говоря, для аутентификации личности также необходимо настроить цифровой сертификат.
Прямая безопасность Прямая секретность первоначально использовалась для определения типа безопасности для протокола обмена ключами рисования. Даже если произошла утечка долгосрочного ключа, это не повлияет на утечку ключа предыдущего сеанса, и содержимое предыдущего сеанса не будет раскрыто.
Чтобы обеспечить прямую безопасность, алгоритмы DH и ECDH добавляют к варианту еще один случайный переменный эфемерный ключ для получения новых алгоритмов DHE и ECDHE.
RSA, DH и DSA реализованы на основе дискретных логарифмов целочисленных конечных полей.
И ECC, и ECDH реализованы на основе задачи дискретного логарифмирования эллиптических кривых.
В настоящее время при реальном использовании предпочтительно ECDHE>DHE> DH,RSA ...ждать.
from typing import Tuple
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.hazmat.primitives.asymmetric.dh import DHParameters, DHPrivateKey, DHPublicKey
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
def data_key_exchange(owner_pri_key: DHPrivateKey, peer_pub_key: DHPublicKey) -> bytes:
shared_key = owner_pri_key.exchange(peer_pub_key)
derived_key = HKDF(algorithm = hashes.SHA256(),
length = 32,
salt = None,
info = b'handshake data',
backend = default_backend()).derive(shared_key)
print("derived_key:{}, length:{}".format(list(derived_key), len(derived_key)))
return derived_key
def generate_common_parameters() -> DHParameters:
parameters = dh.generate_parameters(generator = 2, key_size = 2048,
backend = default_backend())
return parameters
def generate_dh_key(parameters: DHParameters) -> Tuple[DHPrivateKey, DHPublicKey]:
private_key = parameters.generate_private_key()
public_key = private_key.public_key()
return private_key, public_key
if __name__ == '__main__':
param = generate_common_parameters()
a_pri_key, a_pub_key = generate_dh_key(param)
b_pri_key, b_pub_key = generate_dh_key(param)
a_data_key = data_key_exchange(a_pri_key, b_pub_key)
b_data_key = data_key_exchange(b_pri_key, a_pub_key)
print(a_data_key == b_data_key)
Окончательно сгенерированные ключевые данные:
derived_key:[3, 139, 194, 229, 249, 124, 131, 14, 141, 172, 168, 29, 26, 152, 63, 253, 227, 234, 189, 101, 130, 192, 139, 99, 50, 8, 153, 75, 31, 247, 200, 24], length:32
derived_key:[3, 139, 194, 229, 249, 124, 131, 14, 141, 172, 168, 29, 26, 152, 63, 253, 227, 234, 189, 101, 130, 192, 139, 99, 50, 8, 153, 75, 31, 247, 200, 24], length:32
True