Hi I am able to digitally sign a PDF document using iText 5. I have a requirement of signing the PDF again, whereas while validating the PDF it shows that the initial signature is invalid. You can view the file here which was signed again.
See below the code used for sigining,
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
public class Test {
public static void main(String[] args) throws DocumentException, IOException, GeneralSecurityException {
PdfReader reader = null;
PrivateKey pk = null;
String alias = "PRASANTH KARUNAKARAN NAIR";
KeyStore ks = null;
try {
ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
}
catch (KeyStoreException|java.security.NoSuchProviderException e4){
e4.printStackTrace();
}
try {
ks.load(null, null);
}
catch (NoSuchAlgorithmException|java.security.cert.CertificateException|IOException e4){
e4.printStackTrace();
}
try {
pk = (PrivateKey)ks.getKey(alias, "abcd".toCharArray());
}
catch (UnrecoverableKeyException|KeyStoreException|NoSuchAlgorithmException e3){
e3.printStackTrace();
}
Certificate[] chain = null;
try {
chain = ks.getCertificateChain(alias);
}
catch (KeyStoreException e3){
e3.printStackTrace();
}
try {
reader = new PdfReader("D:///signedSample.pdf");
}
catch (IOException e5){
e5.printStackTrace();
}
String signedFileNameWithPath = "D:///signedsignedSample.pdf";
FileOutputStream os = null;
try {
os = new FileOutputStream(signedFileNameWithPath);
}
catch (FileNotFoundException e5){
e5.printStackTrace();
}
PdfStamper stamper = null;
try {
stamper = PdfStamper.createSignature(reader, os,'\0');
}
catch (DocumentException|IOException e5) {
e5.printStackTrace();
}
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
Integer pageNumber = 2;
Rectangle rect=new Rectangle(50,100,220,140);
appearance.setAcro6Layers(false);
appearance.setLayer4Text(PdfSignatureAppearance.questionMark);
appearance.setVisibleSignature(rect,pageNumber, "sig2");
PrivateKeySignature privateKeySignature=null;
try {
privateKeySignature= new PrivateKeySignature(pk, "SHA-256", ks.getProvider().getName());
}
catch (NullPointerException e) {
}
if(privateKeySignature!=null) {
BouncyCastleDigest bouncyCastleDigest = new BouncyCastleDigest();
try {
MakeSignature.signDetached(appearance, (ExternalDigest)bouncyCastleDigest, (ExternalSignature)privateKeySignature, chain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);
}
catch (IOException e1){
e1.printStackTrace();
}
catch (DocumentException e1){
e1.printStackTrace();
}
catch (SignatureException e1) {
e1.printStackTrace();
}
catch (GeneralSecurityException e1){
e1.printStackTrace();
}
}
}
}
Please let me know what went wrong.
