- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
经过广泛的谷歌搜索后,我开始怀疑我是否以某种方式遗漏了数字签名的要点。
这基本上是我认为我原则上应该能够做的事情,我希望 iTextSharp 允许我:
我正在用 C# 和 .NET 编写,并使用 iTextSharp 来解析 PDF 文件。我有一个未签名的 PDF 文件,还有一个相同文件的签名版本。
我知道数字签名从根本上对 PDF 数据进行哈希处理,使用私钥对其进行加密,然后验证过程的一部分是使用公钥对其进行解密,并确保再次进行哈希处理时结果与 PDF 数据匹配。
除此之外,我想获取这个解密的文档哈希,并将其与从我的未签名 PDF 生成的文档哈希进行比较。这是因为我不仅要验证签名的 PDF 是真实的,还要验证它是否与我记录在案的未签名 PDF 相同。我想我也可以通过将 PDF 数据(没有签名)与我记录的 PDF 数据进行比较来做到这一点。
我目前还没有想出如何做到这一点!即:
希望这是清楚的,我没有错过任何地方!
最佳答案
关于这个:
"This is because I not only want to verify that the signed PDF is authentic, but also that it's the same unsigned PDF I have on record"
假设您只想知道您在服务器上获得的文档是真实的:
创建签名文档时,您可以选择只对文件的一部分或整个文档签名。然后您可以使用“整个文档”签名,如果您在服务器上取回的文档是“真实的”(这意味着签名验证成功),那么它肯定与您记录在案的文档相同。
值得一提的是,PDF签名有两种类型,批准签名和认证签名。来自文档 Digital Signatures in PDF from Adobe :
(...) approval signatures, where someone signs a document to show consent, approval, or acceptance. A certified document is one that has a certification signature applied by the originator when the document is ready for use. The originator specifies what changes are allowed; choosing one of three levels of modification permitted:
- no changes
- form fill-in only
- form fill-in and commenting
假设您想要将您在服务器上获得的某些已签名文档与数据库中未签名的等效文档相匹配:
对于文件识别,我建议单独处理。一旦可以打开文档,就可以从所有页面的解压缩内容的串联中创建哈希(例如 md5),然后将其与原始文档中的另一个类似哈希进行比较,(可以生成一次并存储在数据库中)。
我这样做的原因是它独立于文档上使用的签名类型。即使在 PDF 文件中编辑表单域、添加注释或创建新签名,页面内容也不会被修改,它始终保持不变。
如果您使用的是 iText,则可以使用 PdfReader.getPageContent 方法获取页面内容的字节数组。并将结果用于 computing a MD5 hash .
Java 中的代码可能如下所示:
PdfReader reader = new PdfReader("myfile.pdf");
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
int pageCount = reader.getNumberOfPages();
for(int i=1;i <= pageCount; i++)
{
byte[] buf = reader.getPageContent(i);
messageDigest.update(buf, 0, buf.length);
}
byte[] hash = messageDigest.digest();
此外,如果服务器接收到一个文件,该文件未签名而返回时已签名,则签名可能仅引用文件的一部分,而不是全部。在这种情况下,签名摘要可能不足以识别文件。
来自 PDF 规范(我帐户中的粗体部分):
Signatures are created by computing a digest of the data (or part of the data) in a document, and storing the digest in the document.(...) There are two defined techniques for computing a reproducible digest of the contents of all or part of a PDF file:
-A byte range digest is computed over a range of bytes in the file, indicated by the the ByteRange entry in the signature dictionary. This range is typically the entire file, including the signature dictionary but excluding the signature value itself (the Contents entry).
-An object digest (PDF 1.5) is computed by selectively walking a subtree of objects in memory, beginning with the referenced object, which is typically the root object. The resulting digest, along with information about how it was computed, is placed in a signature reference dictionary (...).
关于c# - 使用文档哈希比较签名的 PDF 和未签名的 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12074543/
我想使用 NetworkX Graph 对象作为 Python dict 中的键。但是,我不希望默认的比较行为(即通过对象的地址)。相反,我希望同构图是 dict 中相同元素的键。 此行为是否已在某处
这个问题已经有答案了: What is the most effective way for float and double comparison? (33 个回答) 已关闭 7 年前。 在您认为我
我正在学习 C 编程,为了练习,我找到了一个需要解决的任务。这有点像一个游戏,有人选择一个单词,其他人猜测字母。我必须检查有多少给定的单词可能是所选单词的正确答案。 输入: 3 3//数字 n 和 m
我两天前开始学习C,在做作业时遇到了问题。我们的目的是从字符数组中获取字符列表,并通过计算连续字符并将其替换为数字来缩短它。对“a4b5c5”说“aaaabbbbbccccc”。这是我到目前为止的代码
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
为什么我在 if 中的比较不起作用?答案应该是 8 但它返回 0。 function findMissing(missingArray){ var getArray = missing
我想知道为什么以下 JavaScript 比较会给出不同的结果。 (1==true==1) true (2==true==2) false (0==false==0) false (0==false)
我想知道是否有人可以帮助我完成这个程序。编写一个接受两个字符串的函数。该函数应该将这两个字符串与字典顺序上排在第一位的字符串组合起来。两个字符串之间应该有一个空格。在一行上打印结果字符串。在一行上打印
有谁知道一个免费的开源库(实用程序类),它允许您比较一个 Java bean 的两个实例并返回一个属性列表/数组,这两个实例的值不同?请发布一个小样本。 干杯 托马斯 最佳答案 BeanCompara
我是java新手。任何人都可以给出以下类声明的含义 public class ListNode, V> { K key; V value; ListNode next;
我需要用 C 语言计算和比较 3 种不同大小(100 * 100、1000 * 1000 和 10000 * 10000)的 2 个矩阵相乘的执行时间。我编写了以下简单代码来为 1000 * 1000
当我在 ACCESS 2007 中运行以下 SQL 时 Select Location, COUNT(ApartmentBuildings) AS TotalIBuildingsManaged Fro
根据我对互斥锁的了解——它们通常提供对共享资源的锁定功能。因此,如果一个新线程想要访问这个锁定的共享资源——它要么退出,要么必须不断轮询锁(并在等待锁时浪费处理器周期)。 但是,监视器具有条件变量,它
通常在编程中,不应该比较浮点数据类型是否相等,因为存储的值通常是近似值。 由于两个非整数 Oracle NUMBER 值的存储方式不同(以 10 为基数),是否可以可靠地比较它们是否相等? 最佳答案
使用 PowerShell 时,我们偶尔会比较不同类型的对象。一个常见的场景是 $int -eq $bool (即其中 0 -eq $false 、 0 -ne $true 和任何非零值仅等于真,但不
#include #define MAX 1000 void any(char s1[], char s2[], char s3[]); int main() { char string1[
我想比较两个日期。 从这两个日期中,我只使用 ToShortDateString() 获取日期组件, 如下所示。现在的问题是当我比较两个日期时。它的 throw 错误—— "Operator >= c
用户输入一个数字( float 或整数),并且它必须大于下限。 这是从 UITextField 获取数字的代码: NSNumberFormatter * f = [[NSNumberFormatter
我已经摆弄这段代码大约一个小时了,它让我难以置信。我认为解决方案相当简单,但我似乎无法弄清楚。无论如何,这里去。我制作了一个 javascript 函数来检查用户输入的字符,以便它只能接受 7 个字符
我不太明白为什么当我们在不覆盖 equals 的情况下比较具有相同类属性的两个实例时方法,它将给出 false .但它会给出 true当我们比较一个案例类的两个实例时。例如 class A(val
我是一名优秀的程序员,十分优秀!