Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.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
C# 如何使用iText验证自定义格式的数字签名?_C#_Pdf_Itext_Digital Signature - Fatal编程技术网

C# 如何使用iText验证自定义格式的数字签名?

C# 如何使用iText验证自定义格式的数字签名?,c#,pdf,itext,digital-signature,C#,Pdf,Itext,Digital Signature,我现在正在编写一个pdf查看器,我可以用它将自定义格式的签名(使用中文SM2加密算法,这就是为什么我不能使用标准验证方法,这就是为什么我必须编写自己的pdf查看器)放入pdf并进行检查。签名部分,我计算哈希,然后用usbkey对哈希进行签名,最后我把签名放进了pdf。 但是检查部分,我找不到任何帮助,也不知道该怎么做。我需要找到一种方法来获取原始字节范围并计算哈希值,然后从签名表单字段读取签名。然后将哈希值与旧的哈希值进行比较,以确定文件是否已更改。有人能给我一些示例代码吗 下面是我找到的一些j

我现在正在编写一个pdf查看器,我可以用它将自定义格式的签名(使用中文SM2加密算法,这就是为什么我不能使用标准验证方法,这就是为什么我必须编写自己的pdf查看器)放入pdf并进行检查。签名部分,我计算哈希,然后用usbkey对哈希进行签名,最后我把签名放进了pdf。 但是检查部分,我找不到任何帮助,也不知道该怎么做。我需要找到一种方法来获取原始字节范围并计算哈希值,然后从签名表单字段读取签名。然后将哈希值与旧的哈希值进行比较,以确定文件是否已更改。有人能给我一些示例代码吗

下面是我找到的一些java代码,并将其重写为c#,我认为这可能会有所帮助,尽管有些方法实际上并不存在

  PdfReader pdfReader = new PdfReader("D:\\Hello_world.pdf");
  PdfDocument pdfDocument = new PdfDocument(pdfReader);
  {
       SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
       foreach (String name in signatureUtil.GetSignatureNames())
        {

            PdfSignature signature = signatureUtil.getSignature(name);
            PdfArray b = signature.GetByteRange();
            RandomAccessFileOrArray rf = pdfReader.GetSafeFile();
            Stream rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), SignatureUtil.AsLongArray(b)));
            Stream result = TARGET_STREAM_FOR_name_BYTES;
            {
                 byte[] buf = new byte[8192];
                 int rd;
                 while ((rd = rg.Read(buf, 0, buf.Length)) > 0)
                 {
                      result.Write(buf, 0, rd);
                  }
             }

          }
    }

要判断签名后文件是否已更改,可以使用
SignatureUtl#verifySignature
PdfPKCS7#verify

让我们看看其中一个官方的iText示例,看看它是如何实现的(它是用Java编写的,但是将它移植到C#应该没有问题,因为api完全相同):

更准确地说,您对下一个片段感兴趣:

 public PdfPKCS7 verifySignature(SignatureUtil signUtil, String name) throws GeneralSecurityException, IOException {
    System.out.println("Signature covers whole document: " + signUtil.signatureCoversWholeDocument(name));
    System.out.println("Document revision: " + signUtil.getRevision(name) + " of " + signUtil.getTotalRevisions());
    PdfPKCS7 pkcs7 = signUtil.verifySignature(name);
    System.out.println("Integrity check OK? " + pkcs7.verify());
    return pkcs7;
}
请注意,
SignatureUtil#verifySignature
实际上并没有检查签名的完整性,而只是检查签名的一些属性。其主要目的是创建一个
PdfPKCS7
对象,该对象可用于使用
PdfPKCS7#验证
检查签名的完整性

值得一提的是,上述方法不会检查用于签署文档的证书是否有效。如有必要,应单独检查

总的来说,我建议你阅读(这本书是免费的)。尽管这本书是为iText5编写的,但您可以在iText的github页面上找到完全移植的iText7示例:

另外,由于您没有告诉我们您使用的是哪个iText版本,我在最近的一个版本中给了您一个答案:iText7。然而,由于签名功能刚刚从iText5移植到iText7,因此很容易在iText5中复制答案。只需研究相同的回购示例:
而且。

非常感谢,我会尝试阅读这本书。但我使用的是中文SM2加密算法,这就是为什么我不能使用标准验证方法,这也是为什么我必须编写自己的pdf查看器的原因。在这种情况下,您能给我一些帮助吗?目前iText似乎不支持СццSM2加密算法。我看到有一个关于它的拉取请求,它还没有被接受:现在我们有了SM2库,我的问题是如何获得签名的原始数据和写在pdf签名字典中的签名哈希。如果我能得到它们,我可以使用我的SM2库验证签名,不是吗?我使用的是itextsharp 5.5.8