user2629598 user2629598 - 1 month ago 29
Java Question

Digital signature in pdf using java api and epass2003 token

I am try to add a digital signature to a pdf using java api, and signature was read by epass2003 token. so,here i done this job(add digital signature to pdf),
and its working fine, but when i open this pdf document in another system it shows
the "Atleast one signature has problem", bu in my system validate sign correctly please help me.I have attached my code below please find it.

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<String> 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<CrlClient> crlList = new ArrayList<CrlClient>();
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<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(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);
}
}


so above is my code please help me.

mkl mkl
Answer

Looking at the signature properties one sees:

Signature Properties window

This dialog states the problem:

The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates.

Furthermore a look at the signer's certificate shows:

Certificate viewer window

Thus, your code only embeds the signer certificate itself, not its certificate path (otherwise they would have shown in the certificate viewer window). Unfortunately the issuer certificate (SafeScrypt sub-CA for RCAI Class 2 2014) is not immediately trusted, neither is that certificate's issuer (SafeScrypt CA 2014), but that certificate's issuer (CCA India 2014) in turn is.

Most likely on your computer either the whole certificate chain is known or at least up to a certificate which is explicitly trusted.

To get the same effect on other computers which only know the root certificate, simply add the certificates for "SafeScrypt sub-CA for RCAI Class 2 2014" and "SafeScrypt CA 2014" to your Certificate[] chain.