当前位置: 首页 > 知识库问答 >
问题:

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

蒋星驰
2023-03-14

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

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

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

共有3个答案

齐俊贤
2023-03-14

我也有类似的问题,但我使用的是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();
}
袁凌
2023-03-14

如果您使用的是较新的iText版本,如5.5。x这是一个完整的工作示例,您可以查看数字签名的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
    }
}

使用记录器只是为了显示结果。

严嘉良
2023-03-14

使用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()
 类似资料:
  • 问题内容: 如何使用iText签名pdf?我正在通过此LINK进行操作, 但不了解my_private_key.pfx。我真的需要数字签名证书吗?请澄清一下。提前致谢。 问题答案: 您在问题中提到的文档很好。您必须创建数字签名文件。 该链接具有使用PKCS文件和签署PDF文档的工具。它声称使用iText,因此您应该能够理解这些步骤。源代码在这里

  • 我正在尝试用Itext 5和BouncyCastle 1.48验证PDF签名。我的代码适用于许多已签名的pdf,但也适用于特定客户的某些pdf。这是我的Java代码 有时我会遇到这样的例外: JAVAlang.IllegalArgumentException:getInstance:org中的未知对象。蹦蹦跳跳。asn1。Asn1在组织中列举。蹦蹦跳跳。asn1。ASN1序列。组织上的getIns

  • 首先,虽然我关注StackOverflow已经有相当一段时间了,但这是我第一次发布一些东西,所以如果我做错了或者不按规则做的话,请随时为我指出正确的方向。 我正在开发一个PDF数字签名应用程序,使用iText5,它依赖于一个外部服务,在我准备好PDF签名后提供一个签名哈希。 如iText文档中所述,在第一阶段,我准备了PDF(在最终实现中,所有PDF都可能是多签名的,因此我使用追加模式),如下所示

  • 我有一个pdf文件,需要数字签名,签名是由外部服务提供。在启动签名之前,我没有证书链。我尝试了下面的代码,但是得到了Sigdict/Contents非法的数据消息。 创建文档哈希并将其发布到外部服务以对其进行签名的源 方法getPKCS7DataFromDigitalSignatureResponse(responseXML)用于解析外部服务响应,它将PKCS7作为字符串返回。我试图找出问题的根源

  • 我正在用C#开发一个执行数字签名验证的webserver,以确保pdf文件没有被修改。我使用了iText和iTextSharp。 和我的C#验证码: 在VerifySignature(name)行中;抛出NullReferenceException! 有趣的是,如果我使用C#代码执行签名,我就可以在java中验证它,因为我添加了这些指令:BouncyCastleProvider provider=