У меня сейчас проблема с преобразованием нашей подписи в PDF из хеширования SHA1 в SHA256. Мы используем подход подписи дайджеста, а не подписываем весь PDF.
Я просмотрел ряд статей и дошел до того, что дайджест возвращается в SHA256, однако это делает подпись недействительной (которая ранее была действует). Сообщение об ошибке достоверности: «Документ был изменен или поврежден после того, как подпись была применена»
Я новичок в цифровых подписях, и в результате был бы признателен за любую помощь в этом отношении. Если какая-либо из моих терминов неверна, пожалуйста, не стесняйтесь исправлять меня.
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();
}