Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2012-12-21
17
Medium Priority
?
3,032 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
16 Comments
 
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
Prepare for an Exciting Career in Cybersecurity

Help prevent cyber-threats and provide solutions to safeguard our global digital economy. Earn your MS in Cybersecurity. WGU’s MSCSIA degree program curriculum features two internationally recognized certifications from the EC-Council at no additional time or cost.

 
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
 
LVL 26

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 65

Assisted Solution

by:btan
btan earned 2000 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 65

Accepted Solution

by:
btan earned 2000 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 65

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 Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Sometimes Administrators rights are not enough. These cases call for the SYSTEM account. The process in this article outlines the steps required to execute commands using the SYSTEM account.
With the evolution of technology, we have finally reached a point where it is possible to have home automation features like having your thermostat turn up and door lock itself when you leave, as well as a complete home security system. This is a st…
Simple Linear Regression
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Suggested Courses

824 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