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.
LVL 12
jazzIIIloveAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
btanConnect With a Mentor Exec ConsultantCommented:
I believe the jks is the culprit. For PKCS#12, they are looking at .p12 or .pfx extension file instead of jks.

We can run keytool -list -keystore <keystore_location> and if you see "Keystore type: JKS" then we are creating the wrong keystore instance type in your code.    

Can use -storetype pkcs12 in the keytool command and test again to see Keystore type. This time should show PKCS#12, then test your existing code again.

Otherwise, can also simply change existing code using either  
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
OR
KeyStore ks = KeyStore.getInstance("JKS");

Below is good post - see "How to generate the keys for the self signed mode").
The article also covers code using JKS or PKCS#12 file () which you may find it useful (if bug comes again).

http://itextpdf.sourceforge.net/howtosign.html
0
Get Cisco Certified in IT Security

There’s a high demand for IT security experts and network administrators who can safeguard the data that individuals, corporations, and governments rely on every day. Pursue your B.S. in Network Operations and Security and gain the credentials you need for this high-growth field.

 
jazzIIIloveAuthor Commented:
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.
0
 
jazzIIIloveAuthor Commented:
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.
0
 
CEHJCommented:
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
0
 
jazzIIIloveAuthor Commented:
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.
0
 
CEHJCommented:
Sorry - i have no special knowledge on this. You need to speak to someone who knows about the versions
0
 
jazzIIIloveAuthor Commented:
Hi CEHJ;

Thanks for the information.

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

Regards.
0
 
Tomas Helgi JohannssonCommented:
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
0
 
btanConnect With a Mentor Exec ConsultantCommented:
you may want to check out itextpdf latest version
http://itextpdf.com/examples/iia.php?id=222

They have a pdf ebook on digital signature which is a good lead into the topic, the lowagie package is already a past and they leveraging bouncycastle..

Can check out section "2.2 The “Hello World” of digital signing using iText"
http://itextpdf.com/book/digitalsignatures20121017.pdf

But do also note extract for the ebook below:

Pg24

Part 5—PAdES for XML content describes profiles for XAdES signatures. For instance, after
filling an XFA form, which is XML content embedded in a PDF file, a user may sign selected
parts of the form. This isn’t supported in iText yet.

Pg25

In  versions predating iText 5.3.0,  you’d sign a PDF document choosing one of the following parameters for the setCrypto() method:

¿ PdfSignatureAppearance.WINCER_SIGNED— this created a signature with the sub
filter /adbe.pkcs7.sha1.
¿ PdfSignatureAppearance.SELF_SIGNED— this created a signature with the sub
filter /adbe.x509.rsa_sha1.

These options have been removed in 5.3.0 for very specific reasons. The /adbe.pkcs7.sha1 sub filter will be deprecated in PDF 2.0. ISO-32000-2 recommends: “To support backward compatibility, PDF readers should process this value for the /SubFilter key but PDF writers shall not use this value for that key.” iText is a PDF writer, and since iText 5.3.0, we no longer allow the creation of this type of signatures. Please don’t sign any documents using this sub filter anymore.
0
 
jazzIIIloveAuthor Commented:
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.
0
 
jazzIIIloveAuthor Commented:
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;
0
 
jazzIIIloveConnect With a Mentor Author Commented:
Hi;

Finally, it worked. First I added the bcprov, bcmail, bpg, bcpkix, bctest and then add the following line:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

Thanks for the help.

I will do the verification but really disappointed for such settings and lack of full examples as most of examples don't have the imports or jar references.
0
 
btanExec ConsultantCommented:
Thanks for sharing. glad it helps
0
 
jazzIIIloveAuthor Commented:
Bouncycastle references seems to be fundamental for signing the document..
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.