iText7 多重签名
iText7 multiple signature
我想用 iText7 在 pdf 文档中做多个签名,但问题是当我签名后,它就可以工作了。如果我签名两次,第一次签名无效。看起来像这样:
这是我的代码:
@Test
public void testMutiSign() {
iTextSignerUtil1.SignMultPDF(getBytes(unsignedPath), destPath1);
iTextSignerUtil2.SignMultPDF(getBytes(destPath1), destPath2);
}
IExternalSignatureContainer externalP7DetachSignatureContainer = new IExternalSignatureContainer() {
@Override
public byte[] sign(InputStream data) throws GeneralSecurityException {
//byte[] hashData = HashUtil.hash(data , "SHA256");
byte signData = null;
signData = signUtil.signP7DetachData(data);
return signData;
}
@Override
public void modifySigningDictionary(PdfDictionary signDic) {
signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached);
}
};
public void SignMultPDF(byte[] pdfFile , String destPath , String name , String fname , String value){
boolean success = false;
int estimatedSize = 300000;
while (!success) {
try {
PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(pdfFile));
PdfSigner pdfSigner = new PdfSigner(pdfReader, new FileOutputStream(destPath), true);
pdfSigner.signExternalContainer(externalP7DetachSignatureContainer, estimatedSize);
success = true;
} catch (IOException e) {
e.printStackTrace();
estimatedSize += 1000;
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
}
以上是我所有的示例代码。
还有一个问题,我是否错过了创建签名字段?
这个问题的原因是 original file 的一个怪癖:它有一个空的间接字典,它既用作 Info 字典又用作 大纲 词典。
每当操作 PDF iText 时都会更新其 Info 字典,特别是 ModDate 可能每次都会更改。
因此,在每次签名过程中,Info 字典都会更改,并且随着字典对象的共享,Outlines 字典也是如此.但是不允许更改已签名 PDF 的 Outlines。因此,不允许在创建第二个签名期间更改 Info(和 Outlines)并使第一个签名无效。
这个文件和original file几乎一样,唯一的区别是Info[=38=使用了不同的空字典] 和 Outlines (因为文件中有一个当前未使用的空间接字典,我只需要更改 Info 或 Outlines 这个未使用的对象)。两次签署此文件时,Adobe 不再抱怨。
这是 iText 或 PDF 中的错误吗?我认为 iText 在更改 Info 字典时应该使用新的间接对象编号,因为在 PDF 中通常不禁止重复使用字典。但是一个PDF利用了这样的
重复使用间接宾语真是自找麻烦。所以我认为这个问题同时揭示了 iText 问题和 PDF 中的问题。
我想用 iText7 在 pdf 文档中做多个签名,但问题是当我签名后,它就可以工作了。如果我签名两次,第一次签名无效。看起来像这样:
这是我的代码:
@Test
public void testMutiSign() {
iTextSignerUtil1.SignMultPDF(getBytes(unsignedPath), destPath1);
iTextSignerUtil2.SignMultPDF(getBytes(destPath1), destPath2);
}
IExternalSignatureContainer externalP7DetachSignatureContainer = new IExternalSignatureContainer() {
@Override
public byte[] sign(InputStream data) throws GeneralSecurityException {
//byte[] hashData = HashUtil.hash(data , "SHA256");
byte signData = null;
signData = signUtil.signP7DetachData(data);
return signData;
}
@Override
public void modifySigningDictionary(PdfDictionary signDic) {
signDic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
signDic.put(PdfName.SubFilter, PdfName.Adbe_pkcs7_detached);
}
};
public void SignMultPDF(byte[] pdfFile , String destPath , String name , String fname , String value){
boolean success = false;
int estimatedSize = 300000;
while (!success) {
try {
PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(pdfFile));
PdfSigner pdfSigner = new PdfSigner(pdfReader, new FileOutputStream(destPath), true);
pdfSigner.signExternalContainer(externalP7DetachSignatureContainer, estimatedSize);
success = true;
} catch (IOException e) {
e.printStackTrace();
estimatedSize += 1000;
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
}
以上是我所有的示例代码。
还有一个问题,我是否错过了创建签名字段?
这个问题的原因是 original file 的一个怪癖:它有一个空的间接字典,它既用作 Info 字典又用作 大纲 词典。
每当操作 PDF iText 时都会更新其 Info 字典,特别是 ModDate 可能每次都会更改。
因此,在每次签名过程中,Info 字典都会更改,并且随着字典对象的共享,Outlines 字典也是如此.但是不允许更改已签名 PDF 的 Outlines。因此,不允许在创建第二个签名期间更改 Info(和 Outlines)并使第一个签名无效。
这个文件和original file几乎一样,唯一的区别是Info[=38=使用了不同的空字典] 和 Outlines (因为文件中有一个当前未使用的空间接字典,我只需要更改 Info 或 Outlines 这个未使用的对象)。两次签署此文件时,Adobe 不再抱怨。
这是 iText 或 PDF 中的错误吗?我认为 iText 在更改 Info 字典时应该使用新的间接对象编号,因为在 PDF 中通常不禁止重复使用字典。但是一个PDF利用了这样的 重复使用间接宾语真是自找麻烦。所以我认为这个问题同时揭示了 iText 问题和 PDF 中的问题。