Перейти к основному содержимому

Интеграция с Java

sslTrus предоставляет sslTrusJarsigner Java Provider, который можно использовать вместе со встроенным в JDK инструментом jarsigner для подписания JAR-файлов Java через удалённый сервис подписания кода.

В процессе подписания закрытый ключ подписи кода всегда хранится в облачном HSM. Локально формируются данные для подписания и структура подписи, а сам вызов удалённого сервиса для подписания закрытым ключом выполняется через sslTrusJarsigner Provider.

Помимо подписания JAR, sslTrusJarsigner также поддерживает возможность подписания XMLDSig и может использоваться в сценариях цифровой подписи XML.

Подготовка

Перед использованием подготовьте:

  • JDK 8 или более новую версию.
  • sslTrusJarsigner-<version>.jar.
  • Access Key.
  • Access Secret.
  • Номер сертификата (Cert Code).
  • JAR-файл или XML-файл, который требуется подписать.

В примерах этой статьи <version>, учётные данные доступа, номер сертификата и пути к файлам необходимо заменить на фактические значения.

Загрузка sslTrusJarsigner

Загрузите последний релизный пакет со страницы релизов sslTrusJarsigner и распакуйте его.

Релизный пакет содержит:

sslTrusJarsigner-<version>.jar
SHA-256 校验文件

Рекомендуется перед использованием проверить целостность файла sslTrusJarsigner-<version>.jar по контрольной сумме SHA-256.

Проверка среды выполнения

Сначала убедитесь, что jarsigner, входящий в состав Java и JDK, работает корректно:

java -version
jarsigner -help

Проверьте версию sslTrus Jarsigner:

java -jar sslTrusJarsigner-<version>.jar --version

Просмотр справки:

java -jar sslTrusJarsigner-<version>.jar --help

Если команда jarsigner не существует, убедитесь, что установлен полный JDK, а не только среда выполнения Java Runtime.

Настройка учетных данных доступа

sslTrusJarsigner считывает учетные данные доступа к удаленному сервису подписи кода и номер сертификата через переменные окружения.

Linux и macOS

export SSLTRUS_JARSIGNER_ACCESS_KEY="YOUR_ACCESS_KEY"
export SSLTRUS_JARSIGNER_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SSLTRUS_JARSIGNER_CERT_CODE="YOUR_CERT_CODE"

Windows PowerShell

$env:SSLTRUS_JARSIGNER_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SSLTRUS_JARSIGNER_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SSLTRUS_JARSIGNER_CERT_CODE = "YOUR_CERT_CODE"

Если обслуживающий персонал предоставил специализированный адрес службы, также необходимо настроить SSLTRUS_JARSIGNER_URL.

Linux и macOS:

export SSLTRUS_JARSIGNER_URL="YOUR_SERVICE_URL"

Windows PowerShell:

$env:SSLTRUS_JARSIGNER_URL = "YOUR_SERVICE_URL"

Если выделенный адрес службы не предоставлен, задавать эту переменную не нужно.

Access Secret относится к конфиденциальным учётным данным, его не следует записывать в исходный код, общедоступные файлы конфигурации или журналы сборки. В средах автоматизации рекомендуется внедрять его через CI/CD Secret или другие механизмы управления учётными данными.

Подпись JAR

sslTrusJarsigner интегрируется со стандартным инструментом jarsigner через механизм Java Security Provider.

Пример ниже выполняет:

app-unsigned.jar

После подписания результат будет выглядеть так:

app-signed.jar

JDK 9 или более новая версия

Linux и macOS:

jarsigner \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerPath "sslTrusJarsigner-<version>.jar" \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerPath "sslTrusJarsigner-<version>.jar" `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

JDK 8

Способ загрузки Provider в JDK 8 отличается от JDK 9 и более поздних версий.

Сначала убедитесь:

JAVA_HOME

Укажите полный каталог установки JDK 8.

Linux и macOS:

jarsigner \
-J-cp \
-J"$JAVA_HOME/lib/tools.jar:sslTrusJarsigner-<version>.jar" \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-J-cp `
"-J$env:JAVA_HOME\lib\tools.jar;sslTrusJarsigner-<version>.jar" `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

При использовании обратите внимание:

  • Номер сертификата в конце команды должен совпадать с SSLTRUS_JARSIGNER_CERT_CODE.
  • Рекомендуется использовать -signedjar для вывода в новый файл, чтобы избежать перезаписи исходного JAR.
  • В примере используется SHA256withRSA для завершения подписи кода.
  • Если отметка времени не нужна, можно удалить -tsa и следующий за ним адрес службы отметок времени.

Отметка времени

Для официально выпускаемых JAR-файлов рекомендуется добавлять доверенную отметку времени при подписании.

В примере используется:

http://timestamp.sectigo.com

Соответствующие параметры:

-tsa http://timestamp.sectigo.com

Метка времени используется для подтверждения момента выполнения подписи; исходный JAR-файл не загружается на сервер меток времени.

Если требуется использовать другой сервис меток времени, можно заменить адрес после -tsa на адрес TSA, соответствующий фактической политике подписи.

О различных сервисах меток времени и выборе для производственной среды см. справочные материалы.

Подпись XML

sslTrusJarsigner также предоставляет возможность цифровой подписи XML.

XML-файл может быть подписан командой sign-xml с созданием XMLDSig Enveloped Signature.

В процессе подписи локально формируются структура дайджеста и подписи, необходимые для XMLDSig, а фактическое подписание закрытым ключом RSA выполняется удалённым сервисом подписи кода.

Linux и macOS

java -jar sslTrusJarsigner-<version>.jar \
sign-xml \
"input.xml" \
"signed.xml" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell

java -jar sslTrusJarsigner-<version>.jar `
sign-xml `
"input.xml" `
"signed.xml" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

По умолчанию вывод KeyInfo содержит только конечный сертификат. Если получатель требует, чтобы XML включал полную цепочку сертификатов, можно добавить в конец команды параметр --full-chain.

После завершения выполнения:

input.xml

Для исходного XML-файла,

signed.xml

Для выходного файла, содержащего цифровую подпись XML.

Закрытый ключ для подписи кода не записывается в XML-файл и не сохраняется на локальном компьютере.

Создание файла проверки

После завершения подписи можно создать JKS-файл для проверки подписи.

Linux и macOS:

java -jar sslTrusJarsigner-<version>.jar \
generate-keystore \
"$SSLTRUS_JARSIGNER_CERT_CODE" \
"verify.jks" \
"SSLTRUS"

Windows PowerShell:

java -jar sslTrusJarsigner-<version>.jar `
generate-keystore `
"$env:SSLTRUS_JARSIGNER_CERT_CODE" `
"verify.jks" `
"SSLTRUS"

Генерация:

verify.jks

Этот файл используется только для проверки подписи и не может применяться для подписания кода.

Закрытый ключ для подписания кода по-прежнему хранится в удалённом HSM и не записывается в verify.jks.

Проверка подписи JAR

Используйте сгенерированный verify.jks для проверки подписи:

jarsigner \
-verify \
-verbose \
-certs \
-keystore "verify.jks" \
-storetype JKS \
-storepass "SSLTRUS" \
"app-signed.jar"

Если нужно только просмотреть уже имеющуюся информацию о подписи в JAR-файле, можно выполнить:

jarsigner -verify -verbose -certs "app-signed.jar"

Проверка подписи только проверяет существующую подпись и не вызывает удалённый закрытый ключ для повторного выполнения подписи.

Количество подписей

Количество подписей Jarsigner рассчитывается по фактически успешно выполненным удалённым операциям подписи.

Обычно:

ОперацияКоличество подписей
Успешное однократное подписание одного JAR1 раз
Подписание 3 JAR по отдельности3 раза
Повторное выполнение подписи для того же JARещё 1 раз
jarsigner -verify проверка подписи0 раз
Создание verify.jks0 раз

Таким образом, количество подписей в основном зависит от того, сколько успешных операций подписи было фактически выполнено, а не от количества файлов исходного кода Java-проекта.

Подробные правила см. в справочных материалах.

Часто задаваемые вопросы

Отсутствуют Access Key, Access Secret или номер сертификата

Убедитесь, что в текущем терминале уже заданы:

SSLTRUS_JARSIGNER_ACCESS_KEY
SSLTRUS_JARSIGNER_ACCESS_SECRET
SSLTRUS_JARSIGNER_CERT_CODE

После настройки переменных окружения необходимо выполнить команду подписи в том же сеансе терминала.

Invalid option: -providerPath

Если появится:

Invalid option: -providerPath

Обычно это означает, что используется JDK 8.

JDK 8 не использует параметр -providerPath из примеров для JDK 9 и более новых версий — вместо этого используйте команды для JDK 8, приведённые в этой статье.

Не удаётся загрузить SSLTrusProvider

Если появляется сообщение о невозможности загрузки:

com.racent.codesign.SSLTrusProvider

Проверьте:

  • Правильность пути sslTrusJarsigner-<version>.jar.
  • Соответствие номера версии в имени файла фактическому файлу.
  • Указывает ли JAVA_HOME в среде JDK 8 на полный JDK.

Сертификат или alias не найден

Проверьте:

  • Правильность номера сертификата.
  • Совпадает ли номер сертификата, указанный в конце команды, с SSLTRUS_JARSIGNER_CERT_CODE.
  • Имеют ли текущие Access Key и Access Secret право использовать этот сертификат.

Сбой запроса удалённой подписи

Проверьте:

  • Доступна ли служба удалённой подписи кода из текущей сети.
  • Корректность настроек прокси, брандмауэра и DNS.
  • Правильность Access Key и Access Secret.
  • Правильность номера сертификата.
  • Если используется выделенный адрес службы, настроен ли SSLTRUS_JARSIGNER_URL согласно фактической информации о поставке.

При устранении неполадок можно сохранять полное сообщение об ошибке, но перед отправкой журналов или снимков экрана с ошибкой необходимо удалить или замаскировать чувствительные учётные данные, такие как Access Secret.

Сбой отметки времени

Убедитесь, что текущая сеть может обращаться к серверу отметок времени, указанному в -tsa.

Если это допустимо для бизнеса, можно временно удалить:

-tsa <URL>

Повторно выполните подпись, чтобы определить, возникает ли проблема на этапе удалённого подписания кода или на этапе запроса метки времени.

Примечания по безопасности

В процессе интеграции с Java необходимо учитывать следующее:

  • Access Secret следует хранить как конфиденциальные учётные данные.
  • Не отправляйте учётные данные доступа в репозиторий Git.
  • Не выводите полный Access Secret в журналы.
  • verify.jks используется только для проверки и не содержит закрытый ключ, который можно использовать для удалённого подписания.
  • Локальный Provider sslTrusJarsigner не сохраняет закрытый ключ для подписания кода.
  • Операция подписания закрытым ключом всегда выполняется удалённым сервисом подписания кода.
  • В автоматизированных средах рекомендуется передавать учётные данные доступа через CI/CD Secret или специализированную систему управления учётными данными.

Связанные способы интеграции

Если нужно подписать не Java JAR или XML-файл, можно выбрать другой способ интеграции в зависимости от конкретного сценария:

СценарийСпособ интеграции
Подписание EXE, DLL, MSI и других файлов напрямую из командной строкиКлиентский инструмент
Microsoft SignTool, Visual Studio и другие инструменты WindowsWindows Provider
Автоматизированная сборка в GitHub Actions, Electron Builder и подобных средахCI/CD и инструменты сборки
Самостоятельная разработка клиента удалённого подписанияИнтеграция через API