我在工作时使用PKCS11智能卡,并希望使用jarsigner使用我卡上的证书对jar文件进行签名。
我主要在Linux上工作。酷键可以看到卡片。
Oracle's documentation提到智能卡:
jarsigner -keystore NONE -storetype PKCS11 \
-providerName SunPKCS11-SmartCard \
-list
但显然没有该名称的实际提供者,而jarsigner的-list参数似乎不存在。
我终于让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
我得到了别名列表[来自哪个"身份#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
但我注意到签名的罐子似乎都使用DSA;这可能是问题吗?
答案 0 :(得分:2)
我将-sigalg添加到可用的algortihm [在这种情况下为SHA256withRSA],这有帮助。也:
jarsigner: This jar contains entries whose certificate chain is not validated
我偶然混合了几个不同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是一个只包含notmyrealpass的文件,而card_linux.config是
name=CAC
library=/usr/lib/pkcs11/libcoolkeypk11.so
答案 1 :(得分:0)
与@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
在命令行中不包含卡片PIN会提示输入PIN码(也就是密钥库的密码短语)。
以上内容已经过CAC和Yubikey NEO(PIV配置),JDK-1.8.0_102和Github mouse07410 / OpenSC测试。