Link to home
Start Free TrialLog in
Avatar of jazzIIIlove
jazzIIIloveFlag for Sweden

asked on

Try to sign a document in Java with failure in code.

Hi there;

In Java, I am trying to sign a document and fail to do so. I am using:
itextpdf-5.3.3.jar

My code is as follows:

public void sign()
	{
		KeyStore ks = KeyStore.getInstance("pkcs12");
		ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
		String alias = (String)ks.aliases().nextElement();
		PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
		Certificate[] chain = ks.getCertificateChain(alias);
		PdfReader reader = new PdfReader("original.pdf");
		FileOutputStream fout = new FileOutputStream("signed.pdf");
		PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
		PdfSignatureAppearance sap = stp.getSignatureAppearance();
		sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
		sap.setReason("I'm jazz");
		sap.setLocation("Stockholm");
		// comment next line to have an invisible signature
		sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
		stp.close();
	}

Open in new window


my code gives error in the following lines:
sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
	sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);

Open in new window


What to do?

Regards.
Avatar of Tomas Helgi Johannsson
Tomas Helgi Johannsson
Flag of Iceland image

Avatar of jazzIIIlove

ASKER

Hi;

The errors are compile time error, not runtime errors.

WINCER_SIGNED cannot be resolved or is not a field.
and the other error is as follows:

setVisibleSignature
The method setVisibleSignature(Rectangle, int, String) in the type PdfSignatureAppearance is not applicable for the arguments (Rectangle, int, null)

Regards.

P.S.
I am just trying to sign the pdf, nothing complicated actually. Just for learning purposes.
Hi;

An update: I also tried for the example source code in stackoverflow but the problem is that it uses the old version and when I go for itextpdf package, the above problems emerge again. So, there is no backward compatibility in this.

How can i do this in itextpdf but not in lowagie?

/*
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
*/

import com.itextpdf.text.pdf.*;


regards.
You need to find an example for the api you've got. Either that or get the version of the api for which you have the example
Hi;

I couldn't find the related example for itextpdf for Java (I found C#.NET version). Can you help me on this?

I also tried to find the jdk of the old version but couldn't find its jar.

Regards.
Sorry - i have no special knowledge on this. You need to speak to someone who knows about the versions
Hi CEHJ;

Thanks for the information.

@TomasHelgi:
Can you help me regarding the class PdfSignatureAppearance as it fails for the crypto settings?

Regards.
Hi!

Try to change the line
sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
to
sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, "Some string");

Depending on what kind of certificate you have then also try to change the WINCER_SIGNED to SELF_SIGNED.

And here is an example you could look at and try out.
https://geekcredential.wordpress.com/2010/04/23/how-to-sign-a-pdf-using-itext-and-groovy/comment-page-1/

Regards,
     Tomas Helgi
SOLUTION
Avatar of btan
btan

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi;

Thanks for the help!

I created another jks by issuing:
c:\>keytool -genkey -keyalg RSA -alias "selfsigned" -keystore keystore2.jks -storepass "dummy" -validity 360

my code is as follows:
public void sign()
	{
		try{			
			// String path = properties.getProperty("PRIVATE");
			String keystore_password = "dummy";
			String key_password = "dummy";
			KeyStore ks = KeyStore.getInstance("pkcs12");
			
			ks.load(new FileInputStream("keystore2.jks"), keystore_password.toCharArray());
			
			//ks.load(new FileInputStream("keystore.p12"), keystore_password.toCharArray());
			String alias = (String)ks.aliases().nextElement();
			PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
			Certificate[] chain = ks.getCertificateChain(alias);
			// reader and stamper
			PdfReader reader = new PdfReader("my.pdf");
			FileOutputStream os = new FileOutputStream("my_signed.pdf");
			PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
			// appearance
			PdfSignatureAppearance appearance = stamper .getSignatureAppearance();
			appearance.setImage(Image.getInstance("Image10.jpg"));
			appearance.setReason("I've written this.");
			appearance.setLocation("Foobar");
			appearance.setVisibleSignature(new Rectangle(72, 732, 144, 780), 1,    "first");
			// digital signature
			ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
			ExternalDigest digest = new BouncyCastleDigest();
			MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);
		}catch(Exception ex){ex.printStackTrace();}

	}

Open in new window


Now, my error is no longer compile time but runtime as follows:
java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
      at sun.security.util.DerInputStream.getLength(Unknown Source)
      at sun.security.util.DerValue.init(Unknown Source)
      at sun.security.util.DerValue.<init>(Unknown Source)
      at sun.security.pkcs12.PKCS12KeyStore.engineLoad(Unknown Source)
      at java.security.KeyStore.load(Unknown Source)
and line 34 which is ks.load(...) line.

What to do? Any missing section? Should i do something extra?

Regards.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi;

I think you are right. i changed the keystore instance to JKS and the exception changes as follows:
Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/jcajce/provider/digest/MD2$Digest

ExternalDigest digest = new BouncyCastleDigest();

As referenced library, i have itext-5.3.3.jar

Now, what should I do to fix this classdeffounderror?

Regards.

P.S. I have as:
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of btan
btan

Thanks for sharing. glad it helps
Bouncycastle references seems to be fundamental for signing the document..