?
Solved

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

Posted on 2012-12-21
17
Medium Priority
?
2,950 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 3
  • 3
  • +1
17 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
Need protection from advanced malware attacks?

Look no further than WatchGuard's Total Security Suite, providing defense in depth against today's most headlining attacks like Petya 2.0 and WannaCry. Keep your organization out of the news with protection from known and unknown threats.

 
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 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 64

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 64

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 64

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

Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

Question has a verified solution.

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

What do responsible coders do? They don't take detrimental shortcuts. They do take reasonable security precautions, create important automation, implement sufficient logging, fix things they break, and care about users.
The recent Petya-like ransomware attack served a big blow to hundreds of banks, corporations and government offices The Acronis blog takes a closer look at this damaging worm to see what’s behind it – and offers up tips on how you can safeguard your…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…
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

752 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