【发布时间】:2021-06-20 12:32:11
【问题描述】:
基本上我得到错误 Document has been changed or corrupted since the Signature is applied,我按照 itext 网站的示例并适应了我的情况。
- 准备要签名的文档,添加附加模式,因为它可以 已签署的文件
- 调用 Web 服务对哈希进行签名
- 为准备好的文档添加了签名哈希
我的想法用完了,希望能得到一些帮助 这是我的代码的 sn-p:
public static final String src = "DynamicClient\sample.pdf";
public static final String temp= "DynamicClient\sampleTEMP.pdf";
public static final String dest= "DynamicClient\sampleFINAL.pdf";
public static void emptySignatureSVC(String src, String dest, String fieldname, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException {
PdfReader reader = new PdfReader(src);
reader.setAppendable(true);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0',null,true);
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(0, 0, 0, 0), 1, fieldname);
appearance.setCertificate(chain[0]);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ETSI_CADES_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);
reader.close();
}
public static void createSignatureSVC(String src, String dest, String fieldname, byte[] sign, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException {
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
ExternalSignatureContainer external = new MyExternalSignatureContainer(sign, chain);
MakeSignature.signDeferred(reader, fieldname, os, external);
}
public static void main(String[] args) throws Exception {
Certificate[] chain = signWS.getChain();//External WS to get chain
emptySignatureSVC(src, temp, "signature", chain);
InputStream is = new FileInputStream(new File(temp));
PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false);
byte[] hash = DigestAlgorithms.digest(is, digest.getMessageDigest("SHA256"));
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CADES);
byte[] extSignature = signWS(sh);//External WS to sign
sgn.setExternalDigest(extSignature, null, "RSA");
createSignatureSVC(temp, dest, "signature", sgn.getEncodedPKCS7(hash,null, null, null, CryptoStandard.CADES), chain);
}
这里是文件: original one Signed one
编辑: 忘记添加我使用的容器:
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;
}
@Override
public void modifySigningDictionary(PdfDictionary signDic) {
// TODO Auto-generated method stub
}
}
【问题讨论】:
-
A 你散列了错误的数据;你散列整个准备好的pdf,而你必须散列准备好的pdf,除了要注入的签名容器的占位符。 B您确定需要延期签名吗?
-
A。感谢您的快速回复,我对这个话题有点新手。我虽然签署了错误的数据你有任何关于如何产生正确哈希的例子吗? B - 是的
标签: java pdf itext digital-signature