Solved

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

Posted on 2012-12-21
17
2,757 Views
Last Modified: 2013-01-10
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.
0
Comment
Question by:jazzIIIlove
  • 8
  • 3
  • 3
  • +1
17 Comments
 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 38715167
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 38715416
0
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38718199
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
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38718288
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 38718574
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
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38719077
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 38719101
Sorry - i have no special knowledge on this. You need to speak to someone who knows about the versions
0
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38720870
Hi CEHJ;

Thanks for the information.

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

Regards.
0
New My Cloud Pro Series - organize everything!

With space to keep virtually everything, the My Cloud Pro Series offers your team the network storage to edit, save and share production files from anywhere with an internet connection. Compatible with both Mac and PC, you're able to protect your content regardless of OS.

 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 38729143
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
 
LVL 62

Assisted Solution

by:btan
btan earned 500 total points
ID: 38730415
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
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38745623
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
 
LVL 62

Accepted Solution

by:
btan earned 500 total points
ID: 38746333
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
 
LVL 12

Author Comment

by:jazzIIIlove
ID: 38746551
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
 
LVL 12

Assisted Solution

by:jazzIIIlove
jazzIIIlove earned 0 total points
ID: 38746612
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
 
LVL 62

Expert Comment

by:btan
ID: 38746634
Thanks for sharing. glad it helps
0
 
LVL 12

Author Closing Comment

by:jazzIIIlove
ID: 38762290
Bouncycastle references seems to be fundamental for signing the document..
0

Featured Post

Free camera licenses with purchase of My Cloud NAS

Milestone Arcus software is compatible with thousands of industry-leading cameras for added flexibility. Upon installation on your My Cloud NAS, you will receive two (2) camera licenses already enabled in the software. And for a limited time, get additional camera licenses FREE.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
any built-in Windows Internet browser like wget 11 56
security string in a noisy bar 5 71
iframe detection of parent window scale 20 59
Botnet detection help me please 21 79
Never store passwords in plain text or just their hash: it seems a no-brainier, but there are still plenty of people doing that. I present the why and how on this subject, offering my own real life solution that you can implement right away, bringin…
Every computer eventually fails. When that happens, your valuable data is only as safe as your current backup.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.

929 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now