Подписать JAR без JRE, но с помощью OpenSSL?

Наша система состоит из частей Java и C. На стороне C мы подписываем определенные данные с помощью сценариев командной строки, вызывающих команды OpenSSL. Теперь мы тоже хотим подписать несколько JAR. Мы уже установили PKI (что важно для этого случая - закрытые ключи доступны) "на стороне C", и мы стараемся избегать дублирования / расширения этого на стороне Java.

Какой простой способ получить JAR-подпись для тех, кто не хочет иметь JRE (но имеет OpenSSL)? Т.е. я хочу создать правильный MANIFEST.MF, KEY.SF а также KEY.?SA для моей банки. Их формат не сложен, и это кажется выполнимым с некоторыми сценариями. Кто-нибудь делал это раньше?

1 ответ

Решение

Отвечая на собственный вопрос.

Формат MANIFEST.MF а также KEY.SF задокументировано Oracle. Удивительно, но точное содержание подписи KEY.?SA (где "KEY" - псевдоним хранилища ключей для ключа подписи) в разделе "Файл подписи" не указывается.

это KEY.RSA (для подписей RSA) могут быть созданы средствами командной строки OpenSSL точно так же, как jarsigner создает это. Пример для подписи RSA и дайджеста SHA256:

$ openssl smime -sign -noattr -in META-INF/TEST1.SF -outform der -out META-INF/TEST1.RSA -inkey privateKey.pem -signer cert.pem -md sha256

Аналогичным образом подпись может быть получена с помощью OpenSSL C API. Привязка кода C (без проверки ошибок):

  /* PKCS7_PARTIAL flag is needed to be able to change the digest from the default value */
  PKCS7 *signed_data = PKCS7_sign(NULL, NULL, NULL, data,
    PKCS7_NOATTR | PKCS7_DETACHED | PKCS7_PARTIAL
  );

  digest = EVP_get_digestbyname("sha256");

  PKCS7_sign_add_signer(signed_data, signcert, pkey, digest, flags);

  PKCS7_final(signed_data, NULL, 0);

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

Другие вопросы по тегам