从签名的 pdf 中获取原始内容
Get the original content from a signed pdf
我想知道如何使用 iText java 库或其他库从签名的 pdf 文档中获取原始内容。
谢谢
更新 1:
可能的例子:
PdfReader reader = new PdfReader(PATH_TO_PDF);
AcroFields fields = reader.getAcroFields();
ArrayList<String> signatures = fields.getSignatureNames();
for (String signature : signatures)
{
// Start revision extraction
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte bb[] = new byte[8192];
InputStream ip = fields.extractRevision(signature);
int n = 0;
while ((n = ip.read(bb)) > 0)
out.write(bb, 0, n);
out.close();
ip.close();
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] resum = md.digest(out.toByteArray());
// End revision extraction
}
注1:本例中所有符号都是在多个符号时实现的。
注2:但哈希值不等于原始哈希文档(未签名文档)
请看下图:
在这种情况下,您有一个 PDF 文件(以 %PDF-1.
开头并以 %%EOF
结尾)并且数字签名是文档本身的一部分。它是签名字典中 /Contents
键的值,即签名字段字典中 /V
条目的值。
无法像以前那样获得原始 PDF,因为原始 PDF 已被更改:对象被重新编号,签名字段被添加或
"filled out" 添加签名词典。
您可以删除签名,但这不会为您提供原始 PDF 文件。
PdfReader reader = new PdfReader(SIGNED);
AcroFields acroFields = reader.getAcroFields();
acroFields.removeField("sig");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(UNSIGNED));
stamper.close();
reader.close();
在这种情况下,SIGNED
是签名为 "sig"
的文件的路径。我们删除完整的签名(包括签名字段)。结果文件的路径是 UNSIGNED
,这是一个不再有签名字段痕迹的文件 "sig"
。这不再是签名的原始 PDF。
现在看下图:
这显示了一个包含三个签名的 PDF。第一个签名是按照我之前描述的方式添加的:您无法再获取原始文档。
但是,第二个和第三个签名是在附加模式下添加的。 这是添加额外签名的唯一方法,因为更改修订版 1 会破坏第一个签名。
如果您有修订版 3(标记为 Rev3),则很容易检索修订版 1 和 3(Rev1 和 Rev2)。这显示在 Signatures 示例中:
PdfReader reader = new PdfReader(SIGNED);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(REVISION);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision("first");
int n = 0;
while ((n = ip.read(bb)) > 0)
os.write(bb, 0, n);
os.close();
ip.close();
在此示例中,"first"
是签名字段的名称,SIGNED
是带有签名的文件的路径,REVISION
是从这个操作。
我想知道如何使用 iText java 库或其他库从签名的 pdf 文档中获取原始内容。
谢谢
更新 1:
可能的例子:
PdfReader reader = new PdfReader(PATH_TO_PDF);
AcroFields fields = reader.getAcroFields();
ArrayList<String> signatures = fields.getSignatureNames();
for (String signature : signatures)
{
// Start revision extraction
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte bb[] = new byte[8192];
InputStream ip = fields.extractRevision(signature);
int n = 0;
while ((n = ip.read(bb)) > 0)
out.write(bb, 0, n);
out.close();
ip.close();
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] resum = md.digest(out.toByteArray());
// End revision extraction
}
注1:本例中所有符号都是在多个符号时实现的。
注2:但哈希值不等于原始哈希文档(未签名文档)
请看下图:
在这种情况下,您有一个 PDF 文件(以 %PDF-1.
开头并以 %%EOF
结尾)并且数字签名是文档本身的一部分。它是签名字典中 /Contents
键的值,即签名字段字典中 /V
条目的值。
无法像以前那样获得原始 PDF,因为原始 PDF 已被更改:对象被重新编号,签名字段被添加或 "filled out" 添加签名词典。
您可以删除签名,但这不会为您提供原始 PDF 文件。
PdfReader reader = new PdfReader(SIGNED);
AcroFields acroFields = reader.getAcroFields();
acroFields.removeField("sig");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(UNSIGNED));
stamper.close();
reader.close();
在这种情况下,SIGNED
是签名为 "sig"
的文件的路径。我们删除完整的签名(包括签名字段)。结果文件的路径是 UNSIGNED
,这是一个不再有签名字段痕迹的文件 "sig"
。这不再是签名的原始 PDF。
现在看下图:
这显示了一个包含三个签名的 PDF。第一个签名是按照我之前描述的方式添加的:您无法再获取原始文档。
但是,第二个和第三个签名是在附加模式下添加的。 这是添加额外签名的唯一方法,因为更改修订版 1 会破坏第一个签名。
如果您有修订版 3(标记为 Rev3),则很容易检索修订版 1 和 3(Rev1 和 Rev2)。这显示在 Signatures 示例中:
PdfReader reader = new PdfReader(SIGNED);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(REVISION);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision("first");
int n = 0;
while ((n = ip.read(bb)) > 0)
os.write(bb, 0, n);
os.close();
ip.close();
在此示例中,"first"
是签名字段的名称,SIGNED
是带有签名的文件的路径,REVISION
是从这个操作。