Java 将签名PDF与原始(初始)PDF进行比较
在使用iText对PDF文档进行签名之后,现在我想对签名文档和原始文档进行比较 通常情况下,我应该在原始文件和签名文件之间保持相等(我认为在删除签名后) 我该怎么做 更新1: 以下是我目前使用的函数,该函数允许在检查两个PDF后删除签名,但问题是返回值始终为FALSE:Java 将签名PDF与原始(初始)PDF进行比较,java,itext,signature,Java,Itext,Signature,在使用iText对PDF文档进行签名之后,现在我想对签名文档和原始文档进行比较 通常情况下,我应该在原始文件和签名文件之间保持相等(我认为在删除签名后) 我该怎么做 更新1: 以下是我目前使用的函数,该函数允许在检查两个PDF后删除签名,但问题是返回值始终为FALSE: public static void main(String[] args) throws Exception, GeneralSecurityException, DocumentException { test
public static void main(String[] args) throws Exception,
GeneralSecurityException,
DocumentException {
testRemoveSignatureFromPDFSignedFirmaCerta();
File file1 = new File(SRC);
File file2 = new File(DEST_After_Delete);
boolean compare1and2 = FileUtils.contentEquals(file1, file2);
System.out.println("Are test1.txt and test2.txt the same? " +
compare1and2);
}
public static void testRemoveSignatureFromPDFSignedFirmaCerta() throws
IOException, GeneralSecurityException, DocumentException
{
try ( InputStream inputStream = new FileInputStream(DEST);
OutputStream outputStream = new FileOutputStream(new
File(DEST_After_Delete)))
{
Provider provider = new BouncyCastleProvider();
Security.addProvider(provider);
PdfReader reader = new PdfReader(inputStream, null);
AcroFields af = reader.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
for (String name : names) {
System.out.println("Signature name: " + name);
System.out.println("Signature covers whole document: " +
af.signatureCoversWholeDocument(name));
PdfPKCS7 pk = af.verifySignature(name, provider.getName());
System.out.println("SignatureDate: " + pk.getSignDate());
System.out.println("Certificate: " + pk.getSigningCertificate());
System.out.println("Document modified: " + !pk.verify());
af.removeField(name);
}
PdfStamper stamper = new PdfStamper(reader, outputStream, '\0');
stamper.close();
}
}
publicstaticvoidmain(字符串[]args)引发异常,
一般安全例外,
文档例外{
testRemoveSignatureFromPDFSignedFirmaCerta();
文件file1=新文件(SRC);
文件file2=新文件(删除后删除);
布尔值compare1and2=FileUtils.contentEquals(file1,file2);
System.out.println(“test1.txt和test2.txt是否相同?”+
比较1和2);
}
public static void testRemoveSignatureFromPDFSignedFirmaCerta()抛出
IOException、GeneralSecurityException、DocumentException
{
try(InputStream-InputStream=newfileinputstream(DEST);
OutputStream OutputStream=新文件OutputStream(新
文件(删除后删除)
{
提供程序提供程序=新的BouncyCastleProvider();
Security.addProvider(提供者);
PdfReader reader=新的PdfReader(inputStream,null);
AcroFields af=reader.getAcroFields();
ArrayList name=af.getSignatureNames();
for(字符串名称:名称){
System.out.println(“签名名称:”+名称);
System.out.println(“签名覆盖整个文档:”+
af.签字人对所有文件(名称));
PdfPKCS7 pk=af.verifySignature(名称,provider.getName());
System.out.println(“SignatureDate:+pk.getSignDate());
System.out.println(“证书:+pk.getSigningCertificate());
System.out.println(“文档修改:+!pk.verify());
af.removeField(名称);
}
PdfStamper压模=新的PdfStamper(读卡器,输出流,'\0');
压模关闭();
}
}
视情况而定
生成集成的PDF签名时,通常首先通过
- 选择现有签名字段或添加新的空签名字段李>
- 向该字段添加值字典,包括签名容器最终嵌入的占位符李>
- (可选)更新现有签名或创建新的签名可视化李>
- (可选)如果签名字段具有签名锁字典,则以只读方式呈现分类的其他表单字段李>
- (可选)如果注释尚未出现,则创建并向注释添加外观,以便签名后PDF外观没有变化;及
- (可选)进行任意其他更改,例如修复无效或有问题的PDF对象等
- PDF可以完全重新保存。在这种情况下,建模原始PDF的对象可能会发生实质性变化,它们在文档中的顺序可能会改变,压缩可能会改变,对象可能会重新编号,等等
- 这些更改将作为增量更新附加到原始PDF。在这种情况下,文件的开头仍然是原始PDF的字节
在后一种情况下,您可以通过测试签名PDF文件是否以未签名文件的字节开头,轻松检查签名文件是否确实基于未签名文件。不过,对这些变化本身的评估在这里也很困难。Hi@mkl你对此有什么想法吗?非常感谢你的更新1:如果你读了我的答案,你就会知道这样的方法没有成功的机会。如果签名不是以追加模式/增量更新方式完成的,则根本没有机会从已签名的PDF中检索原始的预签名PDF。是的,您是对的。使用以下链接中的代码:。如何强制附加模式?在创建
PdfStamper
时,使用PdfStamper.createSignature(读卡器,操作系统,'\0',null,true)
而不是PdfStamper.createSignature(读卡器,操作系统,'\0')
强制附加模式。如果我理解正确,即使我将使用附加模式,我也无法从已签名的pdf恢复原始pdf?如果没有,有没有办法做到这一点?