Я хочу иметь возможность захватывать и расшифровывать TLS-трафик, который мое внутреннее приложение (к которому у меня нет доступа) отправляет в Интернет. (Для тестирования я использую Postman для создания запроса на защищенный сервер.)
Я добавил Nginx в качестве обратного прокси.
Я создал самоподписанный сертификат с помощью следующей команды:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt
Я добавил конфигурацию ssl в файл сертификата / etc / nginx / sites-enabled / default.
server {
# SSL configuration
#
listen 443 ssl default_server;
ssl_certificate /home/mavi/nginx/keys/localhost.crt;
ssl_certificate_key /home/mavi/nginx/keys/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass https://myService.com;
proxy_http_version 1.1;
}
}
Я добавил ключ, который создал с помощью OpenSSL в Wireshark Правка> Настройки> SSL> Список ключей RSA.
Почему я не могу расшифровать данные, если использую обмен ключами RSA?
Я исследовал (поправьте меня, если я ошибаюсь) типы асинхронного шифрования. Я знаю, что RSA отправляет клиенту открытый ключ со своим сертификатом, а затем клиент использует этот открытый ключ для шифрования данных. Затем, когда эти зашифрованные данные отправляются на сервер, он использует закрытый ключ для дешифрования информации. Итак, если я использую этот закрытый ключ в Wireshark, я смогу расшифровать данные, верно?
Кроме того, я прочитал, что в целях безопасности мы прекратили использование RSA и теперь перешли на использование алгоритмов Диффи-Хеллмана (ECDH, ECDHE DFH). Diffie Hellman и его варианты больше не используют закрытый ключ, он использует случайные сеансовые ключи, которые сохраняет в ОЗУ. (В качестве примечания для расшифровки пакетов Диффи Хеллмана нам нужно добавить глобальную переменную в систему $ SSLKEYLOGFILE и импортировать этот файл в Wireshark. Это работает только с Google Chrome, Firefox, CURL, но не для внутренних приложений)
Думаю, именно поэтому я не могу расшифровать данные. Потому что при согласовании шифра мой клиент и мой сервер (оба на моем локальном компьютере) используют Diffie Hellman в качестве асинхронного шифрования, даже когда я создаю сертификат RSA. Я предполагаю, что они используют Диффи Хеллмана, потому что в рукопожатии TLS я вижу, что они соглашаются использовать 0xc030
Если я прав, мне следует изменить свой вопрос на Как я могу указать шифры для использования в конфигурации Nginx? Прямо сейчас в моем Nginx включен ssl_prefer_server_ciphers; конфигурация.
Я добавлю рукопожатие TLS, чтобы вы могли видеть согласование шифра. Клиент привет
Сервер привет
Повторное согласование шифра
TLS 1.2 с ECDHE-RSA-AES256-GCM-SHA384 имеет прямую секретность. Обратите внимание на его присутствие на промежуточном уровне Списки шифров Mozilla. Невозможность дешифрования только с помощью ключа сервера - это особенность.
Также извлеките клиентские ключи. Поскольку это завершает TLS на nginx, получите ключи клиента nginx. При отсутствии какой-либо простой опции для включения этого скомпилируйте и загрузите свои собственные хуки. См. Например Извлечение секрета pre-master openssl из nginx который использует чей-то sslkeylog.c. Поскольку API кейлога OpenSSL известен, такая библиотека работает для любого клиента, включая nginx с OpenSSL.
Как обычно, будьте осторожны с проблемами безопасности и эксплуатации при компиляции стороннего кода. Если nginx не является обязательным требованием, рассмотрите другой прокси, где ведение журнала ключей является такой функцией, как митмпрокси
Как я и предполагал, проблема заключалась в шифрах, согласованных между сервером и клиентом.
Мы можем расшифровать пакетные данные TLS / SSL, только если для шифрования данных используются ключи RSA. Если используется эфемерный шифр Диффи-Хеллмана (DHE) или RSA, ключи RSA используются только для защиты обмена DH или RSA, но не для шифрования данных. Таким образом, даже если у вас есть правильный закрытый ключ RSA, вы не сможете расшифровать данные с помощью ssldump, Wireshark или любого другого инструмента. Вы можете проверить, какой набор шифров используется, проверив пакет приветствия сервера, отправленный хостом, который содержит закрытый ключ. Если указанный набор шифров начинается с TLS_DHE или SSL_DHE, вы не сможете расшифровать данные. Если сервер отправляет сообщение ServerKeyExchange, вы не сможете расшифровать данные. Для DHE ваш единственный вариант (если возможно) - изменить конфигурацию клиента или сервера, чтобы не использовались комплекты шифров DHE.
ECDHE или DH (Diffie-Hellman) создают ключи сеанса, к которым могут получить доступ только объекты, участвующие в SSL-соединении. Поскольку ключи сеанса не связаны с парой ключей сервера, только закрытый ключ сервера не может использоваться для расшифровки любого сеанса SSL.
Все наборы шифров TLS_RSA помечены как СЛАБЫЕ, потому что они не обеспечивают прямой секретности, что означает, что в TLS_RSA закрытый ключ используется для расшифровки данных: если закрытый ключ будет скомпрометирован в будущем, весь записанный трафик может быть расшифрован с его помощью .
Теперь отвечу на свой вопрос: Как я могу указать шифры для использования в конфигурации Nginx?
Мне пришлось настроить мой сервер Nginx для использования только шифров TLS_RSA в файле /etc/nginx/nginx.conf
http {
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_ciphers AES256-SHA256:AES256-SHA:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:DES-CBC3-SHA;
}
Таким образом я могу расшифровать данные. Как мы видим на изображении ниже, клиент и сервер согласились использовать TLS_RSA_WITH_AES_256_CBC_SHA (0X0035), и Wireshark может расшифровать данные с помощью закрытого ключа.