gpt4 book ai didi

pdf - iText - 生成没有证书链的 PDF 哈希

转载 作者:行者123 更新时间:2023-12-03 10:59:57 32 4
gpt4 key购买 nike

我正在尝试构建一个发生以下情况的应用程序:

  • 客户端从服务器请求 PDF 哈希。
  • 服务器生成 PDF 文件的哈希值并将其发送给客户端。
  • 客户端用他的私钥签署这个散列,并将签署的散列连同他自己的证书的公共(public)部分一起发送。
  • 服务器生成一个新的签名 PDF 文件。

  • 我遇到的问题是:服务器似乎不可能在没有客户端证书的情况下生成待签名的哈希值。我真的更喜欢创建一个解决方案,其中服务器不需要知道客户端的证书来创建文档摘要。

    到目前为止,我发现的所有示例都使用 PdfPKCS7.getAuthenticatedAttributeBytes 函数来获取待签名的哈希值,但这需要知道客户端证书。我查看了 Bruno Lowagie 的“PDF 文档的数字签名”白皮书,但我没有看到具体消化了哪些信息。

    这是我当前尝试的代码片段:
    public byte[] simplePresign(String src, String digestAlgorithm) throws IOException, DocumentException, GeneralSecurityException {
    this.digestAlgorithm = digestAlgorithm;
    tsaClient = new CustomTSAClient();

    PdfReader reader = new PdfReader(src);
    os = new ByteArrayOutputStream();
    PdfAStamper stamper = PdfAStamper.createSignature(reader, os, '\0', PdfAConformanceLevel.PDF_A_1B);
    appearance = stamper.getSignatureAppearance();

    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    appearance.setCryptoDictionary(dic);

    HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
    exc.put(PdfName.CONTENTS, getEstimatedSize(null, tsaClient) * 2 + 2);
    appearance.preClose(exc);

    InputStream data = appearance.getRangeStream();
    MessageDigest mDigest = DigestAlgorithms.getMessageDigest(digestAlgorithm, null);

    return DigestAlgorithms.digest(data, mDigest);

    }

    不幸的是,这个散列似乎不正确,签署这个散列并根据签名的散列生成一个签名的文档会导致一个无效的签名。

    如果有人可以帮助我改进此代码片段,或者让我深入了解我需要消化的签名数据,我将不胜感激。

    最佳答案

    看来你忽略了DeferredSigning例子。
    在这个例子中,我们首先创建一个带有空签名的 PDF:

    public void emptySignature(String src, String dest, String fieldname, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException {
    PdfReader reader = new PdfReader(src);
    FileOutputStream os = new FileOutputStream(dest);
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
    appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, fieldname);
    appearance.setCertificate(chain[0]);
    ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    MakeSignature.signExternalContainer(appearance, external, 8192);
    }
    授予,公共(public)证书 chain[0]传递给 appearance在本例中,它用于创建视觉外观并创建 PdfPKCS7目的。
    一旦您拥有带有空签名的 PDF,您就可以创建一个 PdfSignatureAppearance在服务器上并获取可以发送到客户端进行签名的哈希。这可以使用 getRangeStream() 来完成。获取需要散列的 PDF 字节范围的方法。此方法返回 InputStream ,可以这样使用:
    BouncyCastleDigest digest = new BouncyCastleDigest();
    PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, null, digest, false);
    byte[] hash = DigestAlgorithms.digest(is, digest.getMessageDigest(hashAlgorithm));
    Calendar cal = Calendar.getInstance();
    byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS);
    现在您可以发送此 sh给客户签字。您将收到另一个 byte[]这是需要添加到 PDF 的实际签名,比方说 byte[]被称为 sig .
    您的外部签名容器可以保持非常简单:它只需要返回签名字节:
    class MyExternalSignatureContainer implements ExternalSignatureContainer {
    protected byte[] sig;
    public MyExternalSignatureContainer(byte[] sig) {
    this.sig = sig;
    }
    public byte[] sign(InputStream is) throws Exception {
    return sig;
    }
    public void modifySigningDictionary(PdfDictionary signDic) {
    }
    }
    您现在可以使用 createSignature()服务器端的方法:
    public void createSignature(String src, String dest, String fieldname, PrivateKey pk, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException {

    PdfReader reader = new PdfReader(src);
    FileOutputStream os = new FileOutputStream(dest);
    ExternalSignatureContainer external = new MyExternalSignatureContainer(sig);
    MakeSignature.signDeferred(reader, fieldname, os, external);
    }

    关于pdf - iText - 生成没有证书链的 PDF 哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29210451/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com