我正在尝试使用智能卡签名pdf。我使用以下代码:
public class SC {
public static final String SRC = "src/test.pdf";
public static final String DEST = "src/test_smartCard.pdf";
public void sign(String src, String dest,
Certificate[] chain, PrivateKey pk,
String digestAlgorithm, String provider, CryptoStandard subfilter,
String reason, String location,
Collection<CrlClient> crlList,
OcspClient ocspClient,
TSAClient tsaClient,
int estimatedSize)
throws GeneralSecurityException, IOException, DocumentException {
// Creating the reader and the stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
// Creating the signature
ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
}
public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {
LoggerFactory.getInstance().setLogger(new SysoLogger());
BouncyCastleProvider providerBC = new BouncyCastleProvider();
Security.addProvider(providerBC);
SunMSCAPI providerMSCAPI = new SunMSCAPI();
Security.addProvider(providerMSCAPI);
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey)ks.getKey(alias, null);
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));
SC app = new SC();
app.sign(SRC, DEST, chain, pk, DigestAlgorithms.SHA256, providerMSCAPI.getName(), CryptoStandard.CMS, "Test", "London",
null, null, tsaClient, 0);
}
}
我对此外部签名过程有些困惑。我已经安装了读卡器,插入了卡,因为我看到它正在使用Windows-MY密钥存储区。因此,只要插入卡,我就可以从该密钥存储区中读出卡上的证书。当我通过Internet Explorer检查证书时,我可以看到从互联网上免费获得的证书以及卡上的证书。我无法从带有私钥的智能卡中导出证书,我知道这是智能卡的全部内容,因此该过程将在外部完成。
我的问题在于,使用我编写的代码,我使用已经制作的证书而不是卡中的证书对文档进行签名,如何用卡中的证书对文档进行签名,还有一件事是从不要求我提供智能卡PIN码。
谁能帮帮我,我正在努力解决这一数字签名问题,我知道接下来的事情是使用PKCS11和dll文件来完成此操作,但是我还没有到此。
添加:
感谢罗伯特的回答。你是对的。我列举了WINDOWS-MY密钥库中的别名,实际上我确实使用列出的第一个别名对文档进行签名,并且这是我的非智能卡证书/密钥对。显然,这不是我想要做的,我将如何使用不同的证书/密钥(在我的情况下,使用属于智能卡的证书/密钥)对其进行签名。再次感谢
通过PDF的别名选择用于签名PDF的证书/密钥。
在您的代码中,您正在使用第一个可用的别名:
String alias = (String)ks.aliases().nextElement();
看起来该别名属于非智能卡证书/密钥对。您应该枚举可用别名(和分配的证书)列表,并查看其中一个是否属于您的智能卡证书。如果智能卡在此列表中不可见,则必须通过PKCS#11访问智能卡。请注意,PKCS#11通常为32位-在这种情况下,您还必须使用32位JRE。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句