Технология единого входа в экосистеме IBM
Технология единого входа (SSO, Single Sign-On) появилась еще в конце 80-х годов и массово применялась уже в начале 2000-х. В наше время сложно встретить IT-специалиста, который бы не сталкивался с этим подходом, только есть пара «но».
Во-первых, в нашем случае использовалась WebSphere — полностью проприетарный продукт, изначально не ориентированный на интеграции за пределами экосистемы IBM.
Во-вторых, платформа была седьмой версии, а с апреля 2018 года производитель полностью завершил ее поддержку. При первом моем знакомстве с этим детищем в 2019 году еще существовала документация и различные официальные статьи. А вот к моменту возникновения рассматриваемой задачи переход из поисковой выдачи чаще завершался призывом купить актуальные продукты. Хотя некоторые заказчики до сих пор эксплуатируют аналогичные решения для выполнения важной бизнес-логики.
Хорошо, что первый релиз седьмой версии платформы состоялся в сентябре 2008 года и что некоторый вариант SSO в ней всё же был реализован. Плохо, что корпоративные гиганты любят максимально привязывать клиентов к своим продуктам, в том числе разрабатывая собственные стандарты, в данном случае — LTPA (Lightweight Third-Party Authentication).
Технология существует в двух похожих версиях, которые различаются алгоритмами хеширования и шифрования отдельных частей. Вторая версия протокола более защищенная, и ее как раз начали использовать в седьмой версии WebSphere. Для конечного пользователя токен единого входа представлен в виде одного cookie-файла с логичным именем LtpaToken2.
А вот его значение на первый взгляд не столь очевидно и выглядит примерно так:
/PSnYKjTLEOXsTLkotp4B6G2yIz8ahqDbuhPdDHKlna8mxj/9YcH/I4HmVjvlisxgxRWtAADFJaJFCG0/cyeFlAM8iOXKnLA58
gednmTBxY2Vhi7el43XfJr6b1/OYtklg3ZPZzmtktrsTvdYXWIqWbrvZrurOQfnh9VeJU5EAOsLfMzHL7woiCJGnd9nPO1qbD8fP
RITM6Veqb0ARmqY5f6oCidJW0gM1hx3RC3Fb0OHWza9MqvkeXiRiDic7gPXVJNHwlsePogRyRMTTxEXi8Z9gnmw0ocoVd6
341lnewCen3HUDlGGgZx9GN/pNHgdSzX9l8JCp06NGtawJPty7za2/NBCGosTYQIr5esFN4=
Если сделать декодирование из Base64, то внутри окажутся бинарные данные, так как содержимое хранится в зашифрованном виде.
Экспорт и анализ ключей шифрования
Для расшифровки нужно в первую очередь получить ключи. Сделать это достаточно просто из консоли администрирования по пути: Security > Global security > LTPA. При экспорте ключей необходимо задать пароль и нужный путь в файловой системе сервера. Далее через SCP (Secure copy — протокол удаленного копирования файлов) загружаем полученный файл для дальнейшего анализа. Теперь нам предстоит взаимодействовать с текстовым файлом, в котором записан небольшой набор свойств в виде «ключ-значение».
<пример выгрузки ключей>
#IBM WebSphere Application Server key file
#Tue Oct 28 19:25:46 MSK 2025
com.ibm.websphere.CreationDate=Tue Oct 28 19:25:46 MSK 2025
com.ibm.websphere.ltpa.version=1.0
com.ibm.websphere.ltpa.3DESKey=amY1JFnk2WXHRqUSteAqGhqRVpFrQVjBp7ji+BJPSDM=
com.ibm.websphere.CreationHost=dev.websphere.local
com.ibm.websphere.ltpa.PrivateKey=s+e2A8iu6V9VZmztiazK/5LS88tDVjGEY1tBeGvMosQI3zZcRDsOSM0qyNoFQ4zDNn3kpGMc
RNuFJ5ICPJF2ThXWwZY/8rxCh4/8ohFnPzVb+weCmJ0GUJbFS/exIt4ulmoIDabWsCyBC+qtgnSj1/K8YlR+ew2A7LUvSnTCrL8XWEhBT6
XZDXE5P/2sjRTzR+iu28WiBWUVlQLJM7IXjKvlGbfRXe1DhpkTmx4CPaFEzEUBblGHiH3izdRCbE9a3oCZlL2S9xkdzAFjjLYFWL/qtQtk
Nhm99l0kGcwuGkgb5isqh4wydlV3Lz68nb2it1Sm6sVt6pp8KB2dEUEPZHicF2DhJGZ/G4WLmk9+rZ4=
com.ibm.websphere.ltpa.Realm=defaultRealm
com.ibm.websphere.ltpa.PublicKey=AMjy/TvoLKK2r4lEwQDdzDM5n/d90PmjPpYCW0eWeoQQ9Z7wHkn+L/D2WBrXTZbTIpmmdnYU3
4Ag9yIjqnKVkpBuwWBvAjmPn0gaSXnAXbTpDHFBF1f+WD5cbNFmMR2P46N49R8y1NQeYbWZG5ZeujYoWcXgqbTHmD/pNoGSPqFxAQAB
</пример выгрузки ключей>
При анализе файла конфигурации следует учитывать два технических несоответствия:
- Параметр ltpa.version содержит устаревшую версию стандарта LTPA 1.0.
- Параметр ltpa.3DESKey сохранил историческое название, хотя фактически ключ уже используется для алгоритма AES.
При использовании значений обязательно нужно обратить внимание на экранирование обратным слешем символа «равно». В приведенном примере оно встречается для свойств com.ibm.websphere.ltpa.3DESKey и com.ibm.websphere.ltpa.PrivateKey.
Расшифровка токена
Как я уже упомянул выше, токен зашифрован по алгоритму AES. Однако ключ шифрования тоже зашифрован, поэтому начать придется с него. Пароль при выгрузке секретов в файл задается не просто так. Именно с помощью него все предоставленные ключи шифруются по алгоритму Triple DES, но и пароль надо использовать не в исходном виде.
В примере выгрузки ключей пароль был password, поэтому алгоритм будет следующий:
- Получаем хеш пароля по алгоритму SHA-1, он будет 160 бит или 20 байт.
- Дополняем это значение до 24 байт, так как нужен 192-битный ключ.
- Формируем непосредственно секрет для расшифровки имеющихся ключей.
<java код> byte[] passwordHash = MessageDigest.getInstance("SHA-1").digest("password".getBytes()); byte[] key = Arrays.copyOfRange(passwordHash, 0, 24); Key secret = SecretKeyFactory.getInstance("DESede").generateSecret( new DESedeKeySpec(key)); </java код>
DESede — это одна из реализаций Triple DES, то есть трехкратного применения алгоритма DES:
- Шифрование с первым подключом.
- Дешифрование со вторым подключом.
- Шифрование с третьим подключом.
Затем надо дешифровать AES-ключ, который в выгрузке ошибочно именован com.ibm.websphere.ltpa.3DESKey. Не забываем сперва убрать лишние символы экранирования из исходного значения, если они присутствуют.
<java код>
byte[] encryptedAESKey = Base64.getDecoder().decode("amY1JFnk2WXHRqUSteAqGhqRVpFrQVjBp7ji+BJPSDM=");
Cipher cipherForAESKey = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipherForAESKey.init(Cipher.DECRYPT_MODE, secret);
Key tokenKey = new SecretKeySpec(cipherForKey.doFinal(encryptedAESKey), 0, 16, "AES")
</java код>
Остается только декодировать и расшифровать сам токен, наконец-то узнав его содержимое.
<java код>
byte[] encryptedBinaryToken = Base64.getDecoder().decode(encodedToken);
Cipher cipherForToken = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipherForToken.init(Cipher.DECRYPT_MODE, tokenKey, new IvParameterSpec(tokenKey.getEncoded()));
byte[] decryptedBinaryToken = cipherForToken.doFinal(encryptedBinaryToken);
</java код>
После преобразования массива байт в строковое представление мы получим:
expire:1761596656000$u:user:defaultRealm/cn=Ivanov,cn=Users,ou=GO,C=RU%1761596656000%CslC39GgF2uKbvUBfpjQsvm
ZZfkyQGH4LaXYikiDm4DOG2TL3BQmckRGZV+9YCo4fikE3UBn789QOBnXA4VZTbOT8nWT3UidVSXkbEflNAjWaPoKoHDCEZQgayfDaetd+rL0
9Ko92asr3r+zo127s0xEv9xI5oLnEmlDQLBixTo=
Для преобразования строкового представления обратно в токен выполняются те же операции, но в противоположной последовательности.
Структура LTPA v2

Токен состоит из трех частей, в качестве разделителя используется символ процента.
Полезная нагрузка (Payload)
Это набор пар «ключ-значение», которые разделяются символом доллара. Ключ отделен от значения двоеточием. Если где-то необходимо использовать один из символов разделителей, то он экранируется символом обратного слеша.
Единственный обязательный элемент — это ключ u, в котором должно быть задано уникальное имя пользователя (DN, Distinguished Name) в определенном формате. Именно его будет использовать система при попытке аутентификации по SSO.
Второй важный, но необязательный ключ — это expire. В нем прописывается временная метка окончания срока жизни токена в миллисекундах, хотя последние три цифры всегда равны нулю, то есть реальная точность — секунды.
Полезная нагрузка может включать дополнительные свойства. Например, WebSphere записывает host — имя сервера или port — номер порта. Кроме того, допустимы свойства с произвольными именами ключей.
Срок жизни (Expire)
Здесь обязательно должна находиться аналогичная временная метка, также в формате миллисекунд, но с фактической точностью до секунд.
Подпись (Signature)
Ее значение формируется по алгоритму SHA1withRSA с применением com.ibm.websphere.ltpa.PrivateKey. Однако подпись вычисляется только по SHA-1 хешу полезной нагрузки. Именно поэтому свойство expire защищено и подписью, и шифрованием, а аналогичная часть токена — только шифрованием.
Для проверки срока жизни WebSphere обращается к временной метке в полезной нагрузке и лишь при ее отсутствии — к аналогичной части токена.
Проверка подписи производится с применением com.ibm.websphere.ltpa.PublicKey. Оба этих ключа сами зашифрованы аналогично AES-ключу.
Сценарии практического применения
В нашем кейсе мы полностью перенесли аутентификацию на новый Identity Provider и LTPA2 всегда генерировали на основании имеющегося JWT (JSON Web Token), либо процесс начинался с формирования последнего.
Для максимальной изоляции двух технологических стеков мы создали промежуточный сервис, отвечающий за кодирование, декодирование и валидацию. Кроме того, в обновленной инфраструктуре заказчик развернул современный LDAP, а учетные записи из устаревшего Tivoli (проприетарной реализации LDAP от IBM) сопоставляются с актуальными по логинам сотрудников.
Понимая устройство токена LTPA2, можно реализовать аналогичные решения единого входа на основе иных современных стандартов аутентификации: SAML 2.0, OpenID Connect и других.
Кроме того, возможны альтернативные варианты применения:
- Расследование инцидентов безопасности. При подозрении на компрометацию сессии можно расшифровать токен и установить, от имени какого пользователя и когда он был создан, чтобы выявить вектор атаки.
- Автоматизированное тестирование. Выполнение тестовых сценариев под разными учетными записями без необходимости ввода паролей и многократного прохождения аутентификации.
- Техническая поддержка. Проверка работы системы под конкретным пользователем без раскрытия его учетных данных.