是否可以使用散列和签名散列对PDF文档进行签名? [英] Is it possible to sign a PDF document with hash and signed hash?

查看:133
本文介绍了是否可以使用散列和签名散列对PDF文档进行签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用带有外部签名的itextpdf库对文档进行签名.

I can sign document using itextpdf library with external signature.

但是问题是最终用户不想发送他的文档,因为它可能包含任何敏感数据.因此,我要求最终用户提供文档哈希值,以便使用外部服务对哈希值进行签名,然后将签名后的哈希值发送回去.

But the problem is that the end user doesn't want to send his document because it may contain any sensitive data. So, I asked the end user to give document hash for signing the hash with external service and send the signed hash back.

但是,这里出现了问题,当他们尝试使用itextpdf(PdfSignatureAppearance)使用给定的已签名哈希对文档进行签名时,PDF文档正在被签名.但是,当验证签名时,它表明签名无效.

But, here comes the problem, when they tried to sign the document with the given signed hash using itextpdf (PdfSignatureAppearance) the PDF document is getting signed. But when verifying the signature it showing that the signature is invalid.

我在这里看到了同样的问题 使用外部服务和iText对PDF签名.

I've seen the same kinda question here Sign PDF using an external service and iText .

因此,之所以会出现此问题,是因为每次使用PdfSignatureAppearance(itextpdf库)打开文档时,哈希都会失效.

So, the problem happens because the hash gets invalidated each time when we open the document using PdfSignatureAppearance (itextpdf library).

任何人都可以告诉我是否可以使用itextpdf库用以前生成的哈希值和签名的哈希值(我从外部服务获得)对PDF文档进行签名,以使哈希值不致失效?

Can anyone please tell me whether it is possible to sign the PDF document with previously generated hash and signed hash (which I got from external service) using itextpdf library so that the hash should not get invalidated?

推荐答案

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

        return sig;

    }
    public void modifySigningDictionary(PdfDictionary signDic) {
    }
}

 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();


         byte[] hash = DigestAlgorithms.digest(inp, digest.getMessageDigest("SHA256"));
         return hash;


    }


public byte[] signed_hash(byte[] hash, PrivateKey pk, Certificate[] chain)throws GeneralSecurityException{
        PrivateKeySignature signature = new PrivateKeySignature(pk, "SHA256", "SunPKCS11-eToken");

        //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);

        byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS);
        byte[] extSignature = signature.sign(sh);

        System.out.println(signature.getEncryptionAlgorithm());

       // Calendar cal = Calendar.getInstance();
        sgn.setExternalDigest(extSignature, null, signature.getEncryptionAlgorithm());
    return sgn.getEncodedPKCS7(hash, cal, 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,pk);
    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);

    }

这篇关于是否可以使用散列和签名散列对PDF文档进行签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆