Как подписать банку смарт-картой

Я использую смарт-карту PKCS11 на работе и хотел бы использовать jarsigner для подписи файлов jar с помощью сертификата на моей карте.

Я в основном работаю над Linux. Coolkey видит карту.

В документации Oracle упоминаются смарт-карты:

jarsigner -keystore NONE -storetype PKCS11 \
    -providerName SunPKCS11-SmartCard \
    -list

Но, по-видимому, настоящего поставщика с таким именем нет, и аргумент -list для jarsigner, похоже, не существует.

Наконец-то я получил jarsigner, чтобы увидеть карту, но он сообщает, что это недействительная запись и не имеет закрытого ключа:

jarsigner -keystore NONE -storetype PKCS11 \
  -providerClass sun.security.pkcs11.SunPKCS11 \
  -providerArg smartcard.config \
  -storepass notmyrealpass \
  myjarfile.jar 'Identity #0'

jarsigner: Certificate chain not found for: Identity #0.
  Identity #0 must reference a valid KeyStore key entry
  containing a private key and corresponding public key
  certificate chain.

Где smartcard.config:

name=Kittens
library=/usr/lib/pkcs11/libcoolkeypk11.so

Я получил список псевдонимов [из которых происходит «Identity # 0»] программно, загрузив карту на Java:

String conf = "name=Kittens\nlibrary=/usr/lib/pkcs11/libcoolkeypk11.so";
InputStream s = new ByteArrayInputStream(conf.getBytes());
Provider p = new sun.security.pkcs11.SunPKCS11(s);
KeyStore keyStore = KeyStore.getInstance("PKCS11", p);
keyStore.load(null, "notmyrealpass".toCharArray());
Enumeration<String> aliases = keyStore.aliases();
// Aliases contains "Identity #0", "Identity #1", "Identity #2"

Вся суть этих смарт-карт в том, что закрытый ключ остается на карте, а карта выполняет подпись; нет способа заставить jarsigner делать то, что я хочу?

РЕДАКТИРОВАТЬ:

Еще немного поработав, я заметил, что, похоже, я не могу использовать SHA1withDSA, только SHA1withRSA:

Set<Provider.Service> services = p.getServices();
for(Provider.Service service : services) {
    System.out.println(service.getAlgorithm());
}

печатает этот список: SHA512withRSA, SHA256withRSA, SHA1withRSA, MD5withRSA, RSA / ECB / PKCS1Padding, SHA384withRSA, MD2withRSA, RSA, PKCS11

Но я заметил, что все подписанные jar-файлы, похоже, используют DSA; это может быть проблемой?


person Gary B    schedule 24.09.2015    source источник
comment
У вас нет прямого опыта, но пытались ли вы сгенерировать пару ключей + сертификат, используя keytool с бэкэндом pkcs # 11 (т.е. с -providerClass и -providerArg)?   -  person vlp    schedule 25.09.2015
comment
Что означает isKeyEntry вернуться к своим псевдонимам? Обратите внимание, что Java обрабатывает только ключи, к которым прикреплены цепочки сертификатов.   -  person Maarten Bodewes    schedule 25.09.2015
comment
isKeyEntry возвращает true; Я также могу сделать keyStore.getCertificateChain (псевдоним) и получить цепочку сертификатов без проблем   -  person Gary B    schedule 25.09.2015


Ответы (2)


Я добавил -sigalg в алгоритм, который был доступен [SHA256withRSA, в данном случае], и это помогло. Также:

jarsigner: этот jar-файл содержит записи, чья цепочка сертификатов не подтверждено

Я случайно микшировал двоичные файлы из пары разных JDK.

Итак, последняя командная строка, которую я использую:

jarsigner \
    -tsa http://timestamp.digicert.com \
    -keystore NONE \
    -storetype PKCS11 \
    -providerClass sun.security.pkcs11.SunPKCS11 \
    -providerArg card_linux.config \
    -storepass `cat ~/cardpass` \
    -sigalg SHA256withRSA \
    dist/sup2rtam.jar \
    'Identity #0'

Где ~ / cardpass - это файл, не содержащий ничего, кроме myrealpass, а card_linux.config - это

name=CAC
library=/usr/lib/pkcs11/libcoolkeypk11.so
person Gary B    schedule 25.09.2015
comment
Рад, что у вас получилось работать; Мне пришлось перепрограммировать всю подпись Java с нуля, потому что я не мог заставить ее работать ... 15 лет назад. - person Maarten Bodewes; 29.09.2015

Подобно тому, что написано выше @Gary B, за исключением того, что я использую OpenSC, и вот моя команда:

jarsigner -tsa http://timestamp.digicert.com \
    -keystore NONE -storetype PKCS11 \
    -providerClass sun.security.pkcs11.SunPKCS11 \
    -providerArg /Library/Java/Extensions/pkcs11.cfg 
    -sigalg SHA256withRSA \
    testjni_signed.jar \
    'Certificate for Digital Signature'

Я использую карту PIV (работает и для CAC). pkcs11.cfg - это

name = OpenSC
library = /Library/OpenSC/lib/opensc-pkcs11.dylib
description = OpenSC PKCS#11 interface for SmartCard
#showInfo = true
slot = 0

Отсутствие ПИН-кода карты в командной строке заставляет его запрашивать ПИН-код (он же Парольная фраза для хранилища ключей).

Вышеупомянутое было протестировано с CAC и Yubikey NEO (в конфигурации PIV), JDK-1.8.0_102 и Github mouse07410 / OpenSC.

person Mouse    schedule 14.08.2016