Я хочу иметь возможность захватывать и расшифровывать трафик 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
#
слушать 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;
расположение / {
# Сначала пытаемся обработать запрос как файл, затем
# в качестве каталога, затем вернитесь к отображению 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 / 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 может расшифровать данные с помощью закрытого ключа.
TLS 1.2 с ECDHE-RSA-AES256-GCM-SHA384 имеет прямую секретность. Обратите внимание на его присутствие на промежуточном уровне списков шифров Mozilla . Особенностью является невозможность дешифрования только с помощью ключа сервера.
Извлеките также ключи клиента. Поскольку это завершает TLS на nginx, получите ключи клиента nginx. При отсутствии какой-либо простой опции для включения этого скомпилируйте и загрузите свои собственные хуки. См., Например, Извлечение секрета pre-master openssl из nginx , который использует чей-то sslkeylog.c . Поскольку API кейлога OpenSSL известен, такая библиотека работает для любого клиента, включая nginx с OpenSSL.
Как обычно, будьте осторожны с безопасностью и операционными проблемами при компиляции стороннего кода. Если nginx не является обязательным требованием, рассмотрите возможность использования другого прокси-сервера, в котором ведение журнала ключей является функцией, например mitmproxy