Itext pdf延迟签名结果为pdf,签名无效

时间:2017-11-27 07:22:20

标签: pdf itext digital-signature

作为我对客户/服务器pdf签名的研究的一部分,我已经测试了itext pdf延迟签名示例。不幸的是,我得到的pdf即合并空签名pdf和哈希值的输出显示无效签名。

我的代码片段如下

 class MyExternalSignatureContainer implements ExternalSignatureContainer {
    protected byte[] sig;
    protected Certificate[] chain;
    public MyExternalSignatureContainer(byte[] sig,Certificate[] chain) {
        this.sig = sig;
        this.chain=chain;
    }
    public byte[] sign(InputStream is)throws GeneralSecurityException  {

        return sig;
    }


public byte[] emptySignature_hash(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);
        InputStream inp = appearance.getRangeStream();   
        BouncyCastleDigest digest = new BouncyCastleDigest();
        PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false);
        byte[] hash = DigestAlgorithms.digest(inp, digest.getMessageDigest("SHA256"));
        Calendar cal = Calendar.getInstance();
        cal1=cal;
        System.out.println(cal);
        byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS);

        return(sh);
    }

public byte[] signed_hash(byte[] hash, PrivateKey pk, Certificate[] chain)throws GeneralSecurityException{
        PrivateKeySignature signature = new PrivateKeySignature(pk, "SHA256", "SunPKCS11-eToken");
        byte[] extSignature = signature.sign(hash);
        //return extSignature;
       BouncyCastleDigest digest = new BouncyCastleDigest();
        Calendar cal = Calendar.getInstance();
        String hashAlgorithm = signature.getHashAlgorithm();
        System.out.println(hashAlgorithm);
        PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false);
        sgn.setExternalDigest(extSignature, null, signature.getEncryptionAlgorithm());
    return sgn.getEncodedPKCS7(hash, cal1, null, null, null, CryptoStandard.CMS);

        }

 public void createSignature(String src, String dest, String fieldname,byte[] hash, PrivateKey pk, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException {

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

public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {

byte[] hh = app.emptySignature_hash(SRC, TEMP, "sig1", chain);
                byte[] hh_sign = (app.signed_hash(hh,  pk,  chain));
                app.createSignature(TEMP, DEST1, "sig1",hh_sign, pk, chain);

}
出了点问题。我想不出来。经常搜索相同的教程。

我正在使用pkcss11 usb令牌进行签名

1 个答案:

答案 0 :(得分:1)

在运行PdfSignatureAppearance appearance之后使用MakeSignature.signExternalContainer时,您的体系结构是错误的。 signExternalContainer中的signDetachedMakeSignature重载都会关闭基础PdfStamperPdfSignatureAppearancePdfReader个实例。

因此,当您在方法emptySignature_hash

中执行以下操作时
    MakeSignature.signExternalContainer(appearance, external, 8192);
    InputStream inp = appearance.getRangeStream();   

您的inp未必包含任何明智的内容。

相反,您应该访问字节范围以登录external对象,它将其作为sign方法的参数进行检索。简单地将哈希计算重构为该方法,并将计算出的哈希值存储在该容器的成员中,以便在emptySignature_hash中检索它。

由于您尚未分享签名代码的示例结果,因此我无法确定您的签名中是否还存在其他问题。