验证PDF是否使用iText进行了数字签名



正如标题所说,我想知道给定的PDF文件是否已经进行了数字签名。

我用iText签署了它,但我不知道它是否已经签署,以最终辞职或执行其他操作。

有没有简单的方法(可能使用iText)?

使用iText:

PdfReader reader = new PdfReader(...);
AcroFields acroFields = reader.getAcroFields();
List<String> signatureNames = acroFields.getSignatureNames();

现在signatureNames包含所有包含签名的可到达签名字段的名称,参见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()

如果您使用的是像5.5.x这样的较新iText版本,这里有一个完整的工作示例,说明如何检查数字签名的PDF(自2.1.7版本以来,iText中进行了许多有用的开发和更改):

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

使用LOGGER只是为了显示结果。

我遇到了类似的问题,但我使用的是itext 7,没有

PdfReader reader = new PdfReader(...);
AcroFields acroFields = reader.getAcroFields();

在当前版本中。

所以我使用了这个解决方案[更新]

private boolean hasSignatures(final PdfDocument pdfDocument) {
    final List<String> signatureNames = new SignatureUtil(pdfDocument).getSignatureNames();
    return !signatureNames.isEmpty();
}

    public static final String verifSign(PdfReader pdfReader)
{
    KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
    AcroFields acroFields = pdfReader.getAcroFields();
    List<String> signatureNames = acroFields.getSignatureNames();
    if (signatureNames.isEmpty())
    {
        return ("El documento no tiene ni una firma registrada");
    }
    for(String name : signatureNames)
    {
        if (!acroFields.signatureCoversWholeDocument(name))
        {
            return ("la firma: "+name+" does not covers the whole document.");
        }
        PdfPKCS7 pk = acroFields.verifySignature(name);
        Certificate[] certificates = pk.getCertificates();
        Calendar cal = pk.getSignDate();
        //System.out.println("Document modified: " + !pk.verify());
        Object fails[] = PdfPKCS7.verifyCertificates(certificates, kall, null, cal);
        if (fails == null)
        {
            // Documento PDF firmado correctamente
        }
        else
        {
            return ("Firma no válida");
        }
    }
    // Todo firmado correctamente
    return null;

}

http://www.berthou.com/us/2009/07/01/verify-pdf-signature-with-itext/

最新更新