пятница, 22 февраля 2013 г.

javax.net.debug: отладка ssl в java

При разработке и настройке защищённых ssl/tls соединений полезен режим отладки. В java для получения такой отладочной информации поможет параметр javax.net.debug.  Далее в посте подробнее о возможностях и результатах.

Есть в java библиотека под названием JSSE - "Java Secure Socket Extension", она же "Расширение java для безопасных сокетов", реализующая протоколы SSL и TLS для обеспечения безопасных соединений. Когда-то давно она была отдельной библиотекой, а с версии jdk1.4 вошла в стандартный дистрибутив. Имено JSSE и содержит возможность трассировки своих операций в поток вывода, что будет полезным при отладке и поиске различных проблем (например, с ошибками рукопожатия или передачи данных, с низкой производительностью и пр.).
 
N. B. Несмотря на то, что JSSE уже много лет, и все эти годы возможность отладки в ней присутствует, в документации говорится, что эта возможность не является официально поддерживаемой функцией - "the debug utility is not an officially supported feature of JSSE".

Какие же значения может принимать этот параметр? Для начала - значение, которое отобразит список доступных опций: -Djavax.net.debug=help. Старт приложения (проверено на jdk 1.6.0 u29) даёт следующий результат:
ERROR [STDERR] all            turn on all debugging
ERROR [STDERR] ssl            turn on ssl debugging
 
ERROR [STDERR] The following can be used with ssl:
ERROR [STDERR]     record       enable per-record tracing
ERROR [STDERR]     handshake    print each handshake message
ERROR [STDERR]     keygen       print key generation data
ERROR [STDERR]     session      print session activity
ERROR [STDERR]     defaultctx   print default SSL initialization
ERROR [STDERR]     sslctx       print SSLContext tracing
ERROR [STDERR]     sessioncache print session cache tracing
ERROR [STDERR]     keymanager   print key manager tracing
ERROR [STDERR]     trustmanager print trust manager tracing
ERROR [STDERR]     pluggability print pluggability tracing
 
ERROR [STDERR]     handshake debugging can be widened with:
ERROR [STDERR]     data         hex dump of each handshake message
ERROR [STDERR]     verbose      verbose handshake message printing
 
ERROR [STDERR]     record debugging can be widened with:
ERROR [STDERR]     plaintext    hex dump of record plaintext
ERROR [STDERR]     packet       print raw SSL/TLS packets

N. B. Если запустить с -Djavax.net.debug=help программу, которая вообще не использует ни одного класса из тех, действия которых утилита призвана логировать, то список опций не будет отображён. Т.е. если написать класс типа классического Hello world и при старте задать ему описываемый параметр, то результата не будет. А вот если в класс добавить, например, инициализацию SSLContext или что-то подобное из JSSE - будет.

Думаю, переводить и пояснять каждую из опций нет смысла. В целом, требования следующие. Параметр должен содержать значение all или ssl - любое из двух. При значении "ssl" логируется подробная информация по всему процессу установления соединения, проверки сертификатов, шифрованию, обмену и пр. При значении "all" к этому добавляются (насколько я могу судить) ещё и дампы - побайтное логирование всей передаваемой информации. У меня для jboss+slf4j+log4j наблюдается ещё такая фишка, как логирование каждого байта на отдельной строке, т.е. если шифрованное сообщение занимает, скажем, 200 байт, лог займёт более 200 новых строк. В итоге при "all" лог быстро разрастается до просто невообразимых размеров. Для сравнения, при обработке одного и того же сообщения между теми же сервером и клиентом с теми же сертификатами размер лога "ssl" составляет ~1490 строк, а "all" ~17900!

Разобраться в таком логе сложно, т.к. он содержит весьма специфичную информацию, для понимания которой желательно иметь как минимум представление о ssl/tls. Если таковое имеется либо есть потребность всё-таки разобраться, то весьма поможет в этом нелёгком деле статья Debugging SSL/TLS Connections, в которой на примере описывается последовательность обмена данными и то, как эта последовательность соотносится с данными лога. Честно, советую хотя бы раз попробовать разобраться - доставляет!

Если для локализации проблем требуется логировать не всё подряд, а конкретные действия и сообщения, то за "ssl" могут следовать уточняющие опции. Можно использовать одну или несколько опций. Разделители между опциями необязательны (т.е. можно и в одно слово писать), хотя для чтения удобно их разделять чем-нибудь, например, запятыми или двоеточиями (естественно, пробелами нельзя). Порядок опций не важен. Примеры:
- hex-дамп всех сообщений рукопожатия:
-Djavax.net.debug=ssl:handshake:data
- hex-дамп всех сообщений рукопожатия + трассировка менеджера ключей:
-Djavax.net.debug=SSL,handshake,data,keymanager

Полезная информация по теме (первоисточники и документация)
http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug
http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/ReadDebug.html (и это же, но в кривом переводе http://spec-zone.ru/RU/Java/Docs/7/technotes/guides/security/jsse/ReadDebug.html)
Esmond Pitt. Fundamental Networking in Java 2006. Section 7.11.













Комментариев нет:

Отправить комментарий