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

Itext 5.5硬件加密。js关于添加签名“文件自签署以来已被更改或损坏”

呼延鹏云
2023-03-14

我正在通过HWCryto-https://github.com/open-eid/hwcrypto.js/wiki/ModernAPI-在Struts2应用程序中添加对数字签名的支持。我先创建了一个空签名,试图跟随布鲁诺·洛瓦吉的书

    CertificateFactory certFactory;
    try {
        certFactory = CertificateFactory.getInstance("X.509");
        ByteArrayInputStream in = new ByteArrayInputStream(certDecoded);
        cert = (X509Certificate) certFactory.generateCertificate(in);
    } catch (CertificateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    Calendar cal = Calendar.getInstance();

    int estimatedSize = 8192;

    PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();

    sap.setVisibleSignature("sig");
    sap.setCertificate(cert);
    sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
    sap.setSignDate(cal);
    ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE,
            PdfName.ADBE_PKCS7_DETACHED);

    try {
        MakeSignature.signExternalContainer(sap, external, 8192);
        pdfStamper.close();
        pdfReader.close();
    } catch (GeneralSecurityException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (DocumentException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

之后,我得到pdf输出,并创建一个新的哈希,我将发送到智能卡

byte [] alteredPDF=output.toByteArray();


    ExternalDigest externalDigest = new ExternalDigest() {
        @Override
        public MessageDigest getMessageDigest(String hashAlgorithm) throws GeneralSecurityException {
            return DigestAlgorithms.getMessageDigest(hashAlgorithm, "BC");
        }
    };
    PdfSignatureAppearance sapFinal = null;
    try {
        ByteArrayOutputStream outputFinal = new ByteArrayOutputStream();
        pdfReader = new PdfReader(new ByteArrayInputStream(alteredPDF));
        pdfStamper = PdfStamper.createSignature(pdfReader, outputFinal, '\0');
        sapFinal = pdfStamper.getSignatureAppearance();
        sapFinal.setVisibleSignature("sig");
        sapFinal.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
        sapFinal.setCertificate(cert);
        sapFinal.setSignDate(cal);

        PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        dic.setReason(sap.getReason());
        dic.setLocation(sap.getLocation());
        String certInfo = cert.getSubjectX500Principal().getName();
        dic.setName(certInfo.substring(certInfo.indexOf("CN=") + 3,
                certInfo.indexOf(",OU", certInfo.indexOf("CN=") + 3)));
        dic.setSignatureCreator(sap.getSignatureCreator());
        dic.setContact(sap.getContact());
        dic.setCert(certDecoded);
        dic.setDate(new PdfDate(sap.getSignDate()));
        sapFinal.setCryptoDictionary(dic);

        HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
        exc.put(PdfName.CONTENTS, new Integer(estimatedSize * 2 + 2));
        sapFinal.preClose(exc);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }catch(Exception e){
        e.printStackTrace();
    }


    byte[] sh = null;
    byte[] hashVal = null;
    PdfPKCS7 sgn = null;



    try {
        sgn = new PdfPKCS7(null, new Certificate[] { cert }, "SHA256", null, externalDigest, false);

        InputStream data = sapFinal.getRangeStream();
        hashVal = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256"));
        sh = sgn.getAuthenticatedAttributeBytes(hashVal, cal, null, null, CryptoStandard.CMS);
        sh = MessageDigest.getInstance("SHA256", "BC").digest(sh);

    } catch (IOException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (GeneralSecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

最后得到了生成的签名

        sgn.setExternalDigest(sig, null, "RSA");
        byte[] encodedSign = null;

        try {
            System.out.println(Arrays.toString(Hex.decodeHex(hash.toCharArray())));
            encodedSign = sgn.getEncodedPKCS7(Hex.decodeHex(hash.toCharArray()), cal, null, null, null,
                    CryptoStandard.CMS);
        } catch (DecoderException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        try {
            MakeSignature.signDeferred(pdfReader, "sig", output,
                    new MyExternalSignatureContainer(encodedSign));
        } catch (DocumentException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (GeneralSecurityException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        System.out.println("called sign pdf");

        try {
            FileOutputStream outputStream = new FileOutputStream("d:\\debug.pdf");
            output.writeTo(outputStream);
            output.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

谁能告诉我我做错了什么?

共有1个答案

孔斌
2023-03-14

终于解决了我的问题。将空签名存储到PDF中并重新创建输出流是罪魁祸首。设法从头到尾使用相同的outputstream,效果很好。此链接-https://github.com/sueastside/BEIDSign/blob/master/beidsign-service/src/main/java/be/redtree/beid/services/SignatureServiceImpl.java-当然帮了我。感谢mkl抽出时间。

 类似资料:
  • 我已经研究了所有类似的问题,但找不到一个应用itextsharp延迟签名的案例。 基本上,我的应用程序使用签名对pdf文档进行签名,该签名是由远程web服务创建的。 我的应用程序向这个web服务发送原始文档的哈希(添加空签名字段后可签名字节的哈希),并接收一个Base64编码的签名文件。 我将此签名嵌入到先前生成的临时pdf文件中,该文件具有空签名字段。 最后,我的签名未被验证,因为Adobe R

  • 我正在使用PDFbox-1.8.8在PDF文件上做签名功能。 当我签署一份文件的时候 下面是我的代码:

  • 我检查了Stackoverflow上的其他类似问题,但它在我的案例中不起作用。 情境:我正在开发一个需要签署pdf文档的应用程序。签名密钥由另一家公司持有,假设它是Companya。 我做了以下几个步骤: null 然后,将消息摘要发送给CompanyA进行签名。在我从CompanyA获得签名的摘要(它是base64编码的)之后,我调用方法来获得签名的pdf文档。 最后我可以得到签名的pdf文档,

  • 对于一个关于签名数据被哈希两次的C#问题,我看到了一个类似的答复,但是我不知道为什么我的签名数据会出现在这里。 C#PKCS7 Smartchard数字签名损坏

  • 我正在为我的应用程序做一个PDF签名功能。以下是工作流程: PDF存储在服务器上。 我将所有必需的签名字段包含到文件中,并使用ZendPDF的扩展名为FaritPDF计算字节长度等。 我根据使用SHA256计算的字节长度计算哈希。 哈希将发送到客户端。 客户端使用PFX文件对哈希进行签名,并创建包含哈希的PKCS7对象。 将PKCS7对象发送到服务器。 PKCS7对象包含在PDF中,并呈现PDF。