Подписанный PDF отсутствует метка времени с сервера меток времени - PullRequest
1 голос
/ 21 января 2020

Я пытаюсь подписать PDF-файл с помощью внешнего веб-сервиса. Этот веб-сервис содержит сертификат пользователя, к которому пользователь может получить доступ с помощью своих учетных данных и кода, сгенерированного одноразовым паролем.

Sidenote: веб-сервис должен ожидать дайджест pdf (ha sh), но странно, что вместо этого он принимает весь файл.

В любом случае реализация выглядит следующим образом:

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;

// OTP = One Time Password code
public void SignPdf(string username, string password, string otp)
{
    byte[] file = GetFileFromPath("D:\test.pdf");
    var fieldName = "signatureField";
    string tempFilePath = "D:\test1temp.pdf");

    using (var pdfReader = new PdfReader(file))
    {
        using (var signedPdf = new FileStream(tempFilePath, FileMode.Create))
        {
            using (var pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0', null, true);
            {
                // Prepare signature
                PdfDate date = new PdfDate();
                var fullSignDate = date.GetW3CDate();
                var signDate = fullSignDate.Substring(0, fullSignDate.IndexOf("T"));
                var signTime = fullSignDate.Substring(fullSignDate.IndexOf("T") + 1);
                var signatureAppearance = pdfStamper.SignatureAppearance;
                signatureAppearance.SetVisibleSignature(fieldName);
                signatureAppearance.Layer2Text=($"Digitally signed by: Test User");

                // Get font
                signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
                signatureAppearance.CryptoDictionary = GetPdfSignature(signatureAppearance);
                signatureAppearance.PreClose(new Dictionary<PdfName, int> { [PdfName.CONTENTS] = 8192 * 2 + 2 });

                // Get file content as base64 string
                var ms = new MemoryStream();
                signatureAppearance.GetRangeStream().CopyTo(ms);
                fileAsBase64 = ms.ToArray();

                // Sign hash (the "hash" is the whole document)
                signature = GetSignedHash(Convert.ToBase64String(fileAsBase64), username, password, otp);

                if (signature != null)
                {
                    EmbedSignatureToPdf(signatureAppearance, signatureWithTimeStamp);
                    success = true;
                }
            }
        }
    }
}

private static PdfDictionary GetPdfSignature(PdfSignatureAppearance sa)
{
    return new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED)
    {
        Reason = sa.Reason,
        Location = sa.Location,
        SignatureCreator = sa.SignatureCreator,
        Contact = sa.Contact,
        Date = new PdfDate(sa.SignDate)
    };
}

private byte[] GetSignedHash(string hash, string username, string password, string otp)
{
    // Call external web service and get a the signed hash
}

private void EmbedSignatureToPdf(PdfSignatureAppearance signatureAppearance, byte[] signature)
{
    var array = new byte[8192];
    Array.Copy(signature, 0, array, 0, signature.Length);
    var pdfDictionary = new PdfDictionary();
    pdfDictionary.Put(PdfName.CONTENTS, new PdfString(array).SetHexWriting(true));
    signatureAppearance.Close(pdfDictionary);
}

PDF успешно подписан, но с использованием Adobe Reader и проверки поля подписи кажется, что доверенная временная метка отсутствует, как вы можете видеть на картинке:

digital signature without timestamp

Похоже, что ответ от удаленного сервиса является объектом подписи, который я просто необходимо вставить в файл PDF.

У меня такой вопрос: поскольку полученная подпись не содержит отметку времени от сервера отметок времени, могу ли я встраивать такую ​​отметку времени на этом этапе или добавить удаленную веб-службу? это перед отправкой мне подписи?

Спасибо!

1 Ответ

1 голос
/ 11 февраля 2020

Поскольку подпись, которую я получаю, не содержит метки времени с сервера меток времени, могу ли я встраивать такую ​​метку времени в этот момент или удаленный веб-сервис должен добавить ее до отправки мне подписи?

Такая метка времени добавляется в контейнер подписи как атрибут unsigned . Поскольку они не подписаны, атрибуты без знака в контейнере подписи могут быть изменены после применения подписи, например, могут быть добавлены дополнительные атрибуты.

Таким образом, вы сами, в частности, можете добавить метку времени к контейнеру подписи, полученному из ваш сервис.

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

...