Как проверить пользовательскую цифровую подпись с помощью iText? - PullRequest
0 голосов
/ 16 января 2019

Сейчас я пишу программу просмотра 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);
                  }
             }

          }
    }

1 Ответ

0 голосов
/ 16 января 2019

Чтобы узнать, был ли файл изменен после подписания, можно использовать SignatureUtl#verifySignature вместе с PdfPKCS7#verify.

Давайте рассмотрим один из официальных примеров iText, чтобы узнать, как это можно сделать (этобыл написан на Java, но не должно быть никаких проблем с портированием его на C #, поскольку API точно такой же): https://github.com/itext/i7js-signatures/blob/develop/src/test/java/com/itextpdf/samples/signatures/chapter05/C5_01_SignatureIntegrity.java

Точнее, вас интересует следующий фрагмент:

 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#verify.

Важно отметить, что приведенные выше методы не проверяют, действительны ли сертификаты, которые использовались для подписи документа.Они должны (при необходимости) проверяться отдельно.

В общем, я советую вам прочитать обзор функций подписи iText (книга бесплатная).Хотя книга была написана для iText5, на странице github iText можно найти полностью перенесенные примеры iText7: https://github.com/itext/i7js-signatures

PS Поскольку вы не сказали нам, какую версию iText вы используете, я далВы ответили в самом последнем: iText7.Однако, поскольку функции подписи были перенесены в iText7 с iText5, ответ легко воспроизвести в iText5.Просто изучите репозитории того же примера: Java one и C # one .

...