【发布时间】:2014-09-03 01:45:18
【问题描述】:
我有一个带有 PDF 数字签名证书的 SafeNet eToken 5100 USB 令牌。我配置了一个 windows 和 mac 系统来使用它,并且我成功地在两台机器上用它的证书手动签署了 PDF 文件。因此,证书按预期工作。
我将令牌发送到我的网络托管公司,他们将它放在我的 Linux (CentOS) 服务器上。我在服务器上安装了 SafeNet Authentication Client。
现在我正在尝试使用 iText 来应用签名。我正在关注这本优秀书籍中的代码示例 4.2:http://itextpdf.com/book/digitalsignatures。我的代码是:
String config = "name = eToken5100_20130805\n" +
"library = /usr/lib64/libeTPkcs11.so\n" +
"slot = 0"; // create a dynamic conf file
ByteArrayInputStream bais = new ByteArrayInputStream(config.getBytes());
Provider providerPKCS11 = new SunPKCS11(bais);
Security.addProvider(providerPKCS11);
System.out.println(providerPKCS11.getName());
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
KeyStore ks = KeyStore.getInstance("PKCS11", providerPKCS11);
ks.load(null, K.PASS_TOKEN);
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey)ks.getKey(alias, K.PASS_TOKEN);
Certificate[] chain = ks.getCertificateChain(alias);
OcspClient ocspClient = new OcspClientBouncyCastle();
TSAClient tsaClient = null;
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = (X509Certificate)chain[i];
String tsaUrl = CertificateUtil.getTSAURL(cert);
if (tsaUrl != null) {
tsaClient = new TSAClientBouncyCastle(tsaUrl);
break;
}
}
List<CrlClient> crlList = new ArrayList<CrlClient>();
crlList.add(new CrlClientOnline(chain));
sign(userFile, userFile_signed, chain, pk, DigestAlgorithms.SHA256, providerPKCS11.getName(),
CryptoStandard.CMS, "Test", "Ghent", crlList, ocspClient, tsaClient, 0);
当我运行此代码时,它会生成以下运行时错误:
stack trace: java.security.KeyStoreException: PKCS11 not found
Caused by: java.security.NoSuchAlgorithmException: no such algorithm:
PKCS11 for provider SunPKCS11-eToken5100_20130805
This link 表示错误的密钥库类型可能会生成此错误。我检查了我的~glassfish/java/jdk7u25/jdk1.7.0_25/jre/lib/security/java.security 文件,它使用了jks 的密钥库。但是,将其更改为 PKCS11 会导致我的 GlassFish 服务器无法重新启动。所以我把它保留为jks。
问题 1:这会导致问题吗?如果有,如何解决?
问题 2:我刚刚在上面的 java 代码中编造了名称eToken5100_20130805...但是这个名称是否需要在某个地方与其他名称匹配? (上面的Java代码是我唯一输入这个名字的地方)。
问题 3:我知道库是正确的,但是如何确定插槽号?我手动输入了插槽 0 到 6(只是猜测),它们每个都产生了上面显示的相同错误。此外,如果我输入插槽号 7 到 10,则每次都会抛出 PKCS11Exception CKR_SLOT_ID_INVALID。
我对这个话题了解不多,但我尝试通过各种方式确定槽号:
(A) 我不确定以下语法是否正确:
# keytool -v -list -keystore NONE -storetype PKCS11 -providername SunPKCS11-eToken5100_20130805 -J-Djava.security.debug=sunpkcs11,pkcs11
但它会返回此输出:
keytool error: java.security.NoSuchProviderException: no such provider: SunPKCS11-eToken5100_20130805
java.security.NoSuchProviderException: no such provider: SunPKCS11-eToken5100_20130805
at sun.security.jca.GetInstance.getService(GetInstance.java:83)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.Security.getImpl(Security.java:698)
at java.security.KeyStore.getInstance(KeyStore.java:661)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:765)
at sun.security.tools.KeyTool.run(KeyTool.java:340)
at sun.security.tools.KeyTool.main(KeyTool.java:333)
(B)我也试过用modutil找槽号:
# modutil -list -dbdir $HOME/.mozilla/firefox/*.default
但我不确定它返回以下内容时的含义:
winscard_clnt.c:420:SCardEstablishContextTH() Your pcscd is too old and does not support CMD_VERSION
winscard_clnt.c:420:SCardEstablishContextTH() Your pcscd is too old and does not support CMD_VERSION
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
2. eToken
library name: libeTPkcs11.so
slots: 6 slots attached
status: loaded
slot:
token:
slot:
token:
slot:
token:
slot:
token:
slot:
token:
slot:
token:
(C) 最后,我尝试运行
# pkcs11-tool --module /usr/lib64/libeTPkcs11.so --list-slots
但这需要先安装 openSC 才能获得 pkcs11-tool。当我尝试使用:# yum install opensc.x86_64 安装时,出现以下错误:
Transaction Check Error:
file /usr/lib64/libpcsclite.so.1.0.0 from install of pcsc-lite-libs-1.5.2-13.el6_4.x86_64
conflicts with file from package libpcsclite1-1.4.0-9.el6.x86_64`
我不知道如何克服这个错误。
我可以使用一些帮助来导航这些不熟悉的错误,了解问题所在,然后如何解决它。看起来槽号确实不正确(槽号可以很大,比如 31310?到目前为止,我假设它们是个位数...),还是别的什么?
--------- 更新 ----------
我的 linux 机器为 libpcsclite1 安装了一个软件包,导致上述错误。我卸载了 SafeNet Auth Client (SAC),删除了这个包,安装了 pcsc-lite(使用 yum),然后重新安装了标准的 SAC。我还使用 yum 安装了 opensc,所以我可以使用 pkcs11-tool。我现在可以使用以下方式查看插槽:
# pkcs11-tool --module /usr/lib64/libeToken.so -L
Available slots:
Slot 0 (0x0): AKS xxxx 00 00
token label: my label
token manuf: SafeNet, Inc.
token model: eToken
token flags: rng, login required, PIN initialized, token initialized, other flags=0x200
serial num : xxxxxxx
Slot 1 (0x1):
(empty)
Slot 2 (0x2):
(empty)
Slot 3 (0x3):
(empty)
Slot 4 (0x4):
(empty)
Slot 5 (0x5):
(empty)
现在我可以运行所有内容而不会产生运行时错误。但是,生成的 PDF 文件显示“至少一个签名无效”。 [更新:我的错误,我正在查看错误的文件。签名的 PDF 文件显示有效签名。]
【问题讨论】:
-
您在哪里找到该设备的 SAC(SafeNet 身份验证客户端)软件?我的理解是,您必须从销售人员那里登录到门户网站.. 我们的 IT 部门拥有.. 但在给我设备并前往周末之前似乎忘记与我分享:-(是否有其他(安全)的地方可以下载它?
-
我没有收到他们门户的登录信息。我刚刚联系了他们的技术支持,他们通过电子邮件向我发送了一个下载链接。 safenet-inc.com/contact-us
标签: java pdf itext keystore pkcs#11