【发布时间】:2015-12-22 16:19:04
【问题描述】:
我在工作中使用 PKCS11 智能卡,并希望使用 jarsigner 使用我卡上的证书对 jar 文件进行签名。
我主要在 Linux 上工作。 Coolkey 可以看到卡片。
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
我通过在 Java 中加载卡以编程方式获得了别名列表 [“Identity #0”来自该列表]:
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;这可能是问题吗?
【问题讨论】:
-
没有直接经验,但您是否尝试使用
keytool和pkcs#11 后端(即-providerClass和-providerArg)生成密钥对+证书? -
isKeyEntry为您的别名返回什么?请注意,Java 仅处理附加了证书链的密钥。 -
isKeyEntry 返回真;我也可以做 keyStore.getCertificateChain(alias) 并毫无问题地取出证书链
标签: java jar cryptography smartcard jarsigner