В подписанном pdf отсутствует временная метка с сервера временных меток

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

Примечание: предполагается, что веб-служба ожидает дайджест PDF (хэш), но, как ни странно, вместо этого он принимает весь файл.

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

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 и проверки поля подписи кажется, что доверенная временная метка отсутствует, как вы можете видеть на картинке:

цифровая подпись без отметки времени

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

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

Благодарю вас!


person iCantSeeSharp    schedule 21.01.2020    source источник
comment
Такая метка времени добавляется в контейнер подписи как неподписанный атрибут. Таким образом, вы сами можете, в частности, добавить отметку времени в контейнер подписи, полученный из вашего сервиса. Однако в зависимости от характера ваших подписей вам, возможно, придется увеличить размер заполнителя в pdf, чтобы было достаточно места для дополнительной отметки времени.   -  person mkl    schedule 22.01.2020
comment
@mkl Спасибо! Я провел более тщательное исследование на основе вашего ответа и нашел способ включить временную метку с помощью программного обеспечения SecureBlackbox. Пожалуйста, добавьте реальный ответ, чтобы я мог его принять.   -  person iCantSeeSharp    schedule 22.01.2020


Ответы (1)


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

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

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

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

person mkl    schedule 11.02.2020