iTextSharp 5 - Обновление подписи SHA1 до SHA256 - PullRequest
0 голосов
/ 13 января 2020

У меня сейчас проблема с преобразованием нашей подписи в PDF из хеширования SHA1 в SHA256. Мы используем подход подписи дайджеста, а не подписываем весь PDF.

Я просмотрел ряд статей и дошел до того, что дайджест возвращается в SHA256, однако это делает подпись недействительной (которая ранее была действует). Сообщение об ошибке достоверности: «Документ был изменен или поврежден после того, как подпись была применена» Signature Properties Image

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

public static byte[] Sign(PdfSignatureAppearance signatureAppearance, IExternalSignature externalSignature, ICollection<X509Certificate> chain, ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype, PdfDictionary customSignatureProperties)
{
    byte[] signedCMS = null;
    List<X509Certificate> certificateChain = new List<X509Certificate>(chain);
    ICollection<byte[]> crlBytes = BuildCrlBytes(certificateChain, crlList);

    if (estimatedSize == 0)
    {
        estimatedSize = CalculateEstimatedSizeOfSignature(crlBytes, ocspClient, tsaClient);
    }

    signatureAppearance.CryptoDictionary = CreateCryptoDictionary(signatureAppearance, customSignatureProperties, PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    signatureAppearance.PreClose(SignGetEstimatedSizeDictionary(estimatedSize));

    using (Stream data = signatureAppearance.GetRangeStream())
    {
        byte[] documentHash = DigestAlgorithms.Digest(data, externalSignature.GetHashAlgorithm());
        signedCMS = externalSignature.Sign(documentHash);
        byte[] encodedSignatureWithTimestamp = SignAddTimestampToSignedCms(tsaClient, signedCMS);

        if (SignCheckEstimatedSize(encodedSignatureWithTimestamp, estimatedSize))
        {
            byte[] paddedSignature = new byte[estimatedSize];
            Array.Copy(encodedSignatureWithTimestamp, 0, paddedSignature, 0, encodedSignatureWithTimestamp.Length);

            signatureAppearance.Close(SignGetDigestDictionary(paddedSignature));
        }
    }
    return signedCMS;
}

private static PdfDictionary CreateCryptoDictionary(PdfSignatureAppearance signatureAppearance, PdfDictionary customSignatureProperties, PdfName filter, PdfName subFilter)
{
    PdfSignature dictionary = new PdfSignature(filter, subFilter);
    dictionary.Reason = signatureAppearance.Reason;
    dictionary.Location = signatureAppearance.Location;
    dictionary.Contact = signatureAppearance.Contact;
    dictionary.Date = new PdfDate(signatureAppearance.SignDate);
    if (customSignatureProperties != null)
    {
        dictionary.PutAll(customSignatureProperties);
    }

    return dictionary;
}

private static byte[] SignAddTimestampToSignedCms(ITSAClient tsaClient, byte[] signedCms)
{
    ArrayList newSigners = new ArrayList();
    CmsSignedData cmsSignedData = new CmsSignedData(signedCms);
    foreach (SignerInformation information in cmsSignedData.GetSignerInfos().GetSigners())
    {
        byte[] signedDigest = information.GetSignature();
        byte[] timestampImprint = DigestAlgorithms.Digest(tsaClient.GetMessageDigest(), signedDigest);
        byte[] timestampToken = tsaClient.GetTimeStampToken(timestampImprint);

        newSigners.Add(SignerInformation.ReplaceUnsignedAttributes(information, GenerateUnsignedAttributes(Constants.TIMESTAMP_OID, timestampToken)));
    }

    return CmsSignedData.ReplaceSigners(cmsSignedData, new SignerInformationStore(newSigners)).GetEncoded();
}

Редактирование: добавление в код, реализованный реализацией метода IExternalSignature Sign

public static byte[] SignDigest(string signer, byte[] digest)
{
  SignatureData data = ConfigurationHelpers.GetSignatureData(signer);
  var cryptoServiceProvider = RSACryptoServiceProvider)data.SigningCertificate.PrivateKey;    // verify private key access
  var contentInfo = new ContentInfo(digest);
  var signedCms = new SignedCms(contentInfo);
  var cmsSigner = new CmsSigner(data.SigningCertificate);
  cmsSigner.IncludeOption = X509IncludeOption.WholeChain;
  signedCms.ComputeSignature(cmsSigner);
  //  Encode the CMS/PKCS #7 message.
  return signedCms.Encode();
}
...