As the title says I want to know if a given PDF file is already digitally signed.
I used iText to sign it but I'm not able to know if it is already signed to eventually resign it or perform other actions.
Is there a way to do it simply (possibly using iText)?
When you open the document with a PDF reader or browser you will see that the document has been given a front page that says that the document is signed. There you will find information about when the document is signed, by whom and what electronic ID that has been used.
Open the Preferences dialog box. Under Categories, select Signatures. For Verification, click More. To automatically validate all signatures in a PDF when you open the document, select Verify Signatures When The Document Is Opened.
Look for: detailed audit trails documenting each stage of the signing process; software that complies with international eSigning regulations; signer authentication to prove the signer is who they say they are; and.
Open the PDF document in Adobe Reader showing the “At least one signature has problems” error. Click on the Signature Panel button, which will be on the right of the error. Click on the Validate all link. It will prompt the message to validate all signatures depending on the settings.
Using iText:
PdfReader reader = new PdfReader(...);
AcroFields acroFields = reader.getAcroFields();
List<String> signatureNames = acroFields.getSignatureNames();
Now signatureNames
contains the names of all reachable signature fields containing signatures, cf. the JavaDoc:
/**
* Gets the field names that have signatures and are signed.
*
* @return the field names that have signatures and are signed
*/
public ArrayList<String> getSignatureNames()
If you are using newer iText version like 5.5.x here is a full working example how you can check a digitally signed PDF (a lot of useful development and changes have been done in iText since version 2.1.7):
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DigitalSignatureCheck {
private static final Logger LOGGER = LoggerFactory.getLogger(DigitalSignatureCheck.class);
public static final boolean verifySignature(PdfReader pdfReader)
throws GeneralSecurityException, IOException {
boolean valid = false;
AcroFields acroFields = pdfReader.getAcroFields();
List<String> signatureNames = acroFields.getSignatureNames();
if (!signatureNames.isEmpty()) {
for (String name : signatureNames) {
if (acroFields.signatureCoversWholeDocument(name)) {
PdfPKCS7 pkcs7 = acroFields.verifySignature(name);
valid = pkcs7.verify();
String reason = pkcs7.getReason();
Calendar signedAt = pkcs7.getSignDate();
X509Certificate signingCertificate = pkcs7.getSigningCertificate();
Principal issuerDN = signingCertificate.getIssuerDN();
Principal subjectDN = signingCertificate.getSubjectDN();
LOGGER.info("valid = {}, date = {}, reason = '{}', issuer = '{}', subject = '{}'",
valid, signedAt.getTime(), reason, issuerDN, subjectDN);
break;
}
}
}
return valid;
}
private static void validate(String name)
throws IOException, GeneralSecurityException {
InputStream is = DigitalSignatureCheck.class.getClassLoader()
.getResourceAsStream(name);
PdfReader reader = new PdfReader(is);
boolean ok = verifySignature(reader);
LOGGER.info("'{}' is {}signed", name, ok ? "" : "NOT ");
}
public static void main(String[] args) throws Exception {
validate("any.pdf"); // if placed in resources' root
}
}
Using the LOGGER is just for displaying the result.
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