带签名文件的iTextsharp [英] iTextsharp with signed file
问题描述
我对PDF签名有问题.我收到了一个使用生命周期(Acrobat)创建的PDF文件,该文件已经在某些acroField上包含两个数字签名.我必须将几个数据放在其他Acrofield上,并且在C#中使用以下代码:
I have a problem with PDF signed. I received a PDF file, created with Life Cycle (Acrobat) that already contain two digital signing over some acroFields. I have to put a couple of data over other acrofields, and I´m using the follow code in C#:
PdfReader pdfReader = null;
PdfStamper stamper = null;
string filePDF = @"C:\Visual Studio Solutions\Visual Windows\cpce Certificaciones\prueba_xfa.pdf";
string outPDF = @"C:\Visual Studio Solutions\Visual Windows\cpce Certificaciones\prueba_xfa_out.pdf";
try
{
using (var inStream = new FileStream(filePDF, FileMode.Open))
{
pdfReader = new PdfReader(inStream);
}
using (var outStream = new FileStream(outPDF, FileMode.Create))
{
stamper = new PdfStamper(pdfReader, outStream, '\0', true);
var form = stamper.AcroFields;
form.SetField("FORMULARIO[0].SUBFORMULARIO[0].ConsejoSubForm[0].OBLEA[0]", "probando");
stamper.Close();
pdfReader.Close();
}
}
catch (Exception ex)
{
throw new Exception("error: " + ex.Message);
}
问题是新文件的前两个签名已损坏. 我不知道怎么了. 预先感谢
The problem is the new file has the two previous signing broken. I don´t know what is wrong. Thanks in advance
推荐答案
考虑问题的注释,您观察到iTextSharp/C#代码破坏了先前的签名,而iText/Java代码破坏了前一个签名.一.因此,这里有两个有趣的主题:
- 为什么C#和Java代码会有不同的结果?
- 为什么签名完全被破坏?
- Why is there a different outcome of C# and Java code?
- Why are signatures broken at all?
我试图重现此问题.但是,不幸的是,我得到了不同的结果,在这里C#和Java版本都只破坏了第一个签名.因此,我在这里尝试解释为什么第一个签名被破坏.
Adobe Acrobat签名属性显示未操纵PDF的原始版本.因此,您的代码添加的增量更新中所做的某些更改被视为无效. Acrobat在ConsejoSubForm.OBLEA
,ContribuyenteSubForm.FECHA_CIERRE
,ContribuyenteSubForm.FECHA_REALIZACION
,ContribuyenteSubForm.LeyendaAdjuntarArchivo
和Encabezado.FECHA_ACTUAL
字段中列出了修改(我在这里删除了所有[0]
和FORMULARIO[0].SUBFORMULARIO[0]
前缀).
Adobe Acrobat signature properties show that the original revision of the PDF was not manipulated. Thus, some of the changes made in the incremental update added by your code are considered invalid. Acrobat lists modifications in the fields ConsejoSubForm.OBLEA
, ContribuyenteSubForm.FECHA_CIERRE
, ContribuyenteSubForm.FECHA_REALIZACION
, ContribuyenteSubForm.LeyendaAdjuntarArchivo
, and Encabezado.FECHA_ACTUAL
(I dropped all the [0]
s and the FORMULARIO[0].SUBFORMULARIO[0]
prefix here).
检查XFA会发现签名字段FIRMA_CONTRIBUYENTE
(包含第一个签名的字段)不允许更改作为camposFirmaContribuyente
收集的字段.除ConsejoSubForm.OBLEA
之外的所有修改字段都在此集合中.
Inspecting the XFA one finds that the signature field FIRMA_CONTRIBUYENTE
(the field containing the first signature) disallows changes to the fields collected as camposFirmaContribuyente
; of the modified fields all but ConsejoSubForm.OBLEA
are in this collection.
因此,由于四个FECHA_*
和Leyenda*
字段的变化,第一个签名显示为已损坏.
Thus, the first signature is displayed as broken because of changes in the four FECHA_*
and Leyenda*
fields.
确实,正如您自己说的,日期字段已清除.而且,如果您仔细观察一下Leyanda的价值,就会发现与众不同.
Indeed, as you have said yourself, the date fields are cleared. And if you look at the Leyanda value closely, you'll find a difference.
该代码仅用于更改ConsejoSubForm.OBLEA
字段(不受第一个签名保护),而不能更改其他四个字段.那么为什么还要更改它们呢?
The code is meant to only change the ConsejoSubForm.OBLEA
field (which is not protected by the first signature) but not the four other ones. So why are they changed, too?
首先,比较签名前后的XFA表单XML,可以看到唯一的变化(超过等效的XML序列化)确实是ConsejoSubForm.OBLEA
的值.特别是,其他具有声明更改的四个字段在XFA XML中未更改 !
First of all, comparing the XFA form XMLs before and after signing, one sees that the only change (in excess of equivalent XML serialization) indeed is the value of ConsejoSubForm.OBLEA
. In particular, the four other fields with claimed changes are not changed in the XFA XML!
因此,iText既没有明确地更改其不打算更改的字段,也不能在XFA XML中找到其他更改.
Thus, neither did iText explicitly change fields it was not meant to change nor can those other changes be found in the XFA XML.
在XFA XML中搜索四个FECHA_*
和Leyenda*
字段值时,会发现这些值不是{http://www.xfa.org/schema/xfa-form/2.8/}:form
部分中.
Searching for the four FECHA_*
and Leyenda*
field values in the XFA XML one finds that these values are not contained in the {http://www.xfa.org/schema/xfa-data/1.0/}:datasets
section (which according to the XFA specification contains all the sets of data used with the form) but instead in a separate {http://www.xfa.org/schema/xfa-form/2.8/}:form
section.
在XFA规范3.3中未指定此部分.
此部分引人注目的是{http://www.xfa.org/schema/xfa-form/2.8/}:form
元素包含checksum
属性:
One thing about this section that strikes the eye is that {http://www.xfa.org/schema/xfa-form/2.8/}:form
element contains a checksum
attribute:
<form xmlns="http://www.xfa.org/schema/xfa-form/2.8/"
checksum="Y3ReuUF4b/rARe9AfHzXknOOs5Q=">
此属性实际上是Bruno Lowagie提出的此问题的重点.
This attribute actually is the focus of this question by Bruno Lowagie.
我对此的解释:
- Adobe使用XFA XML的这一专有部分来存储XFA数据集中未包含的额外表单数据.
- 此外,它在整个表单状态的某种表示形式上存储校验和,以确定该专有部分仍基于其他表单数据的当前状态.
- iText不会更新此未记录的校验和.
- 因此,在打开表单时,Adobe Acrobat将检测到基础表单数据存在与专有
{http://www.xfa.org/schema/xfa-form/2.8/}:form
部分不同步的更改,并重新初始化此部分中的数据,从而更改了根据各自的字段定义,四个FECHA_*
和Leyenda*
字段值. - 在验证第一个签名时,Adobe Reader确定签名字段定义不允许由于重新初始化而导致的更改,并将签名显示为损坏.
- Adobe uses this proprietary part of the XFA XML to store extra form data which are not contained in the XFA datasets.
- Furthermore, it stores a checksum over some representation of the whole form state to determine that this proprietary part is still based on the current state of the other form data.
- iText did not update this undocumented checksum.
- Adobe Acrobat, therefore, upon opening the form detects that there are changes to the underlying form data not synchronized with the proprietary
{http://www.xfa.org/schema/xfa-form/2.8/}:form
section and re-initializes the data in this section which changes the fourFECHA_*
andLeyenda*
field values according to the respective field definitions. - When validating the first signature, Adobe Reader determines that the changes due to that re-initialization are not allowed by the signature field definition and displays the signature as broken.
在手头的XFA表单中,某些表单数据和表单数据校验和使用了XFA规范的专有Adobe扩展.由于此扩展名未公开记录,因此iText无法对其进行适当的更新.这使Adobe Acrobat认为iText更新了OBLEA字段后签名已损坏.
In the XFA form at hand proprietary Adobe extensions to the XFA specification were used for some form data and a form data checksum. As this extension is not publicly documented, iText could not update it appropriately. This made Adobe Acrobat consider the signature broken after iText updated the OBLEA field.
此类专有的添加可能是在PDF 2.0 XFA表单中声明已弃用的原因.
Such proprietary additions might be the reason why in PDF 2.0 XFA forms have been declared deprecated.
因此,如果要使用iText编辑XFA表单,请确保该表单完全符合XFA规范中的规定,并且不包含专有扩展名.
If you want to edit XFA forms with iText, therefore, please make sure that the form completely is as specified in the XFA specification and does not contain proprietary extensions.
这篇关于带签名文件的iTextsharp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!