使用java api和epass2003令牌的pdf数字签名

我尝试使用java api为pdf添加数字签名,并通过epass2003令牌读取签名。 所以,在这里我完成了这项工作(将数字签名添加到pdf中),并且工作正常,但是当我在另一个系统中打开此pdf文档时,它显示“Atleast one signature has problem”,在我的系统中正确validation符号请帮助我已经附上了我的代码,请找到它。

public class Test { public static void main(String args[]) throws IOException, GeneralSecurityException, DocumentException, CertificateVerificationException{ // Create instance of SunPKCS11 provider String userFile = "C:/results/test.pdf"; String userFile_signed = "C:/results/test_signed.pdf"; String pkcs11Config = "name=eToken\nlibrary=C:\\Windows\\System32\\eps2003csp11.dll"; java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes()); sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(pkcs11ConfigStream); java.security.Security.addProvider(providerPKCS11); // Get provider KeyStore and login with PIN String pin = "12345678"; java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS11", providerPKCS11); keyStore.load(null, pin.toCharArray()); // Enumerate items (certificates and private keys) in the KeyStore java.util.Enumeration aliases = keyStore.aliases(); String alias = null; while (aliases.hasMoreElements()) { alias = aliases.nextElement(); System.out.println(alias); } PrivateKey pk = (PrivateKey)keyStore.getKey(alias, "12345678".toCharArray()); Certificate[] chain = keyStore.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 crlList = new ArrayList(); crlList.add(new CrlClientOnline(chain)); Test t = new Test(); t.sign(userFile, userFile_signed, chain, pk, DigestAlgorithms.SHA256, providerPKCS11.getName(), CryptoStandard.CMS, "Test", "Signature", crlList, ocspClient, tsaClient, 0); } public void sign(String src, String dest, Certificate[] chain, PrivateKey pk, String digestAlgorithm, String provider, CryptoStandard subfilter, String reason, String location, Collection 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(100, 100, 200, 200), 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); } } 

所以上面是我的代码请帮帮我。

看一下签名属性:

签名属性窗口

此对话框说明了问题:

签名者的身份未知,因为它尚未包含在您的可信证书列表中,并且其父证书都不是可信证书。

此外,看一下签名者的证书显示:

证书查看器窗口

因此,您的代码仅嵌入签署者证书本身,而不是其证书路径(否则它们将显示在证书查看器窗口中)。 遗憾的是,颁发者证书(RCAI Class 2 2014的SafeScrypt子CA)不是立即信任的,该证书的颁发者(SafeScrypt CA 2014)也不是,但该证书的颁发者(CCA India 2014)依次是。

最有可能在您的计算机上整个证书链是已知的,或者至少是明确信任的证书。

要在仅知道根证书的其他计算机上获得相同的效果,只需将“SafeScrypt sub-CA for RCAI Class 2 2014”和“SafeScrypt CA 2014”的Certificate[] chainCertificate[] chain