Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将签名PDF与原始(初始)PDF进行比较_Java_Itext_Signature - Fatal编程技术网

Java 将签名PDF与原始(初始)PDF进行比较

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

在使用iText对PDF文档进行签名之后,现在我想对签名文档和原始文档进行比较

通常情况下,我应该在原始文件和签名文件之间保持相等(我认为在删除签名后)

我该怎么做

更新1: 以下是我目前使用的函数,该函数允许在检查两个PDF后删除签名,但问题是返回值始终为FALSE:

 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的字节
(如果签名与iText一起应用:在iText中作为增量更新应用更改是通过使用追加模式完成的。)

在前一种情况下,比较是非常困难的,特别是如果有很多“任意的其他变化”。此外,您也不能期望通过删除签名来恢复原始PDF,它在内部可能仍然非常不同。我这里没有一个容易实现的想法


在后一种情况下,您可以通过测试签名PDF文件是否以未签名文件的字节开头,轻松检查签名文件是否确实基于未签名文件。不过,对这些变化本身的评估在这里也很困难。

Hi@mkl你对此有什么想法吗?非常感谢你的更新1:如果你读了我的答案,你就会知道这样的方法没有成功的机会。如果签名不是以追加模式/增量更新方式完成的,则根本没有机会从已签名的PDF中检索原始的预签名PDF。是的,您是对的。使用以下链接中的代码:。如何强制附加模式?在创建
PdfStamper
时,使用
PdfStamper.createSignature(读卡器,操作系统,'\0',null,true)
而不是
PdfStamper.createSignature(读卡器,操作系统,'\0')
强制附加模式。如果我理解正确,即使我将使用附加模式,我也无法从已签名的pdf恢复原始pdf?如果没有,有没有办法做到这一点?