I am receiving the following exception regarding PKCS12 certificate 1. unwrapping private key 2. illegal key size The following is my actual exception which I received.
Exception in thread "main" java.io.IOException: exception unwrapping private key - java.security.InvalidKeyException: Illegal key size
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.unwrapKey(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at Signatures.signPdfFirstTime(Signatures.java:103)
at Signatures.main(Signatures.java:229)
This is my actual code on which I am working
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.CertificateInfo;
import com.itextpdf.text.pdf.security.CertificateVerification;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.itextpdf.text.pdf.security.VerificationException;
public class Signatures {
/** The resulting PDF */
public static String ORIGINAL = "C://Proj1//hello.pdf";
/** The resulting PDF */
public static String SIGNED1 = "C://Proj1//signature_1.pdf";
/** The resulting PDF */
public static String SIGNED2 = "C://Proj1//signature_2.pdf";
/** Info after verification of a signed PDF */
public static String VERIFICATION = "results/part3/chapter12/verify.txt";
/** The resulting PDF */
public static String REVISION = "results/part3/chapter12/revision_1.pdf";
/**
* A properties file that is PRIVATE.
* You should make your own properties file and adapt this line.
*/
public static String PATH = "C://Proj1//keystore.properties";
/** Some properties used when signing. */
public static Properties properties = new Properties();
/** One of the resources. */
public static final String RESOURCE = "C://Proj1//logo.jpeg";
/**
* Creates a PDF document.
* @param filename the path to the new PDF document
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
document.add(new Paragraph("Hello World!"));
document.close();
}
/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfFirstTime(String src, String dest)
throws IOException, DocumentException, GeneralSecurityException {
//String path = properties.getProperty("PRIVATE");
char[] str="mysecret".toCharArray();
String path="C://Proj1//keystore.p12";
//String keystore_password = properties.getProperty("PASSWORD");
String key_password="C://Proj1//keystore.propertise";
// String key_password = properties.getProperty("PASSWORD");
KeyStore ks = KeyStore.getInstance("PKCS12","BC");
ks.load(new FileInputStream(path), str);
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(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// appearance
PdfSignatureAppearance appearance = stamper .getSignatureAppearance();
appearance.setImage(Image.getInstance(RESOURCE));
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);
}
/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfSecondTime(String src, String dest)
throws IOException, DocumentException, GeneralSecurityException {
String path = "C://Proj1//.keystore";
String keystore_password = "ram007";
String key_password = "ram0075";
String alias = "agreeya";
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream(path), keystore_password.toCharArray());
PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
// reader / stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
// appearance
PdfSignatureAppearance appearance = stamper
.getSignatureAppearance();
appearance.setReason("I'm approving this.");
appearance.setLocation("Foobar");
appearance.setVisibleSignature(new Rectangle(160, 732, 232, 780), 1, "second");
// 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);
}
/**
* Verifies the signatures of a PDF we've signed twice.
* @throws GeneralSecurityException
* @throws IOException
*/
public void verifySignatures() throws GeneralSecurityException, IOException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X509");
FileInputStream is1 = new FileInputStream(properties.getProperty("ROOTCERT"));
X509Certificate cert1 = (X509Certificate) cf.generateCertificate(is1);
ks.setCertificateEntry("cacert", cert1);
FileInputStream is2 = new FileInputStream("resources/encryption/foobar.cer");
X509Certificate cert2 = (X509Certificate) cf.generateCertificate(is2);
ks.setCertificateEntry("foobar", cert2);
PrintWriter out = new PrintWriter(new FileOutputStream(VERIFICATION));
PdfReader reader = new PdfReader(SIGNED2);
AcroFields af = reader.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
for (String name : names) {
out.println("Signature name: " + name);
out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
out.println("Document revision: " + af.getRevision(name) + " of " + af.getTotalRevisions());
PdfPKCS7 pk = af.verifySignature(name);
Calendar cal = pk.getSignDate();
Certificate[] pkc = pk.getCertificates();
out.println("Subject: " + CertificateInfo.getSubjectFields(pk.getSigningCertificate()));
out.println("Revision modified: " + !pk.verify());
List<VerificationException> errors = CertificateVerification.verifyCertificates(pkc, ks, null, cal);
if (errors.size() == 0)
out.println("Certificates verified against the KeyStore");
else
out.println(errors);
}
out.flush();
out.close();
}
/**
* Extracts the first revision of a PDF we've signed twice.
* @throws IOException
*/
public void extractFirstRevision() throws IOException {
PdfReader reader = new PdfReader(SIGNED2);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(REVISION);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision("first");
int n = 0;
while ((n = ip.read(bb)) > 0)
os.write(bb, 0, n);
os.close();
ip.close();
}
/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
* @throws GeneralSecurityException
*/
public static void main(String[] args)
throws IOException, DocumentException, GeneralSecurityException {
Security.addProvider(new BouncyCastleProvider());
properties.load(new FileInputStream(PATH));
Signatures signatures = new Signatures();
signatures.createPdf(ORIGINAL);
signatures.signPdfFirstTime(ORIGINAL, SIGNED1);
signatures.signPdfSecondTime(SIGNED1, SIGNED2);
// signatures.verifySignatures();
// signatures.extractFirstRevision();
}
}
Did you read Digital signatures for PDF documents?
I quote:
Don’t panic if you get an
InvalidKeyException
saying that the key size is invalid. Due to import control restrictions by the governments of a few countries, the encryption libraries shipped by default with the Java SDK restrict the length, and as a result the strength, of encryption keys. If you want to avoid this problem, you need to replace the default security JARs in your Java installation with the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. These JARs are available for download from http://java.oracle.com/ in eligible countries.
Did you install the Java Cryptography Extension?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With