Статус: Активный участник
Группы: Участники
Зарегистрирован: 05.04.2020(UTC) Сообщений: 45  Откуда: Москва Сказал(а) «Спасибо»: 24 раз
|
Наверное, пора сдаваться. И не пытаться скрестить ежа с со слоном. В общем споткнулся на том, что скрещиваю нескрещиваемое... (с встраиванием в PDF): Код:X509CertificateParser parser = new X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain =
new Org.BouncyCastle.X509.X509Certificate[] { parser.ReadCertificate(x509.RawData) };
sap.Certificate = chain[0];
sap.SignDate = DateTime.Now;
sap.Reason = "Reason!";
sap.Location = "Location!";
// Выбираем подходящий тип фильтра
PdfName filterName = new PdfName("CryptoPro PDF");
// Создаем подпись
PdfSignature dic = new PdfSignature(filterName, PdfName.ADBE_PKCS7_DETACHED);
dic.Date = new PdfDate(DateTime.Now);
dic.Name = "Sign-test";
dic.Reason = "Reason!";
dic.Location = "Location!";
sap.CryptoDictionary = dic;
//какая-то магия, но видимо тут и определяется массив для подписи
int intCSize = 8000; //4000
Dictionary<PdfName, int> hashtable = new Dictionary<PdfName, int>();
hashtable[PdfName.CONTENTS] = intCSize * 2 + 2;
sap.PreClose(hashtable);
Stream s = sap.GetRangeStream();
MemoryStream ms = new MemoryStream();
int read = 0;
byte[] buff = new byte[8192];
while ((read = s.Read(buff, 0, 8192)) > 0)
{
ms.Write(buff, 0, read);
}
Далее следует все как в примере у нормальных людей: Код://ContentInfo - тип PKCS #7 (как я прочел)
ContentInfo contentInfo = new ContentInfo(ms.ToArray());
SignedCms signedCms = new SignedCms(contentInfo, true);
CmsSigner cmsSigner = new CmsSigner(x509);
byte[] pk = null;
signedCms.ComputeSignature(cmsSigner, false); //если не ввести container password - исключение
pk = signedCms.Encode();
var www = Convert.ToBase64String(pbSignedMessageBlob); //это просто глазами смотрел
byte[] outc = new byte[intCSize];
PdfDictionary dic2 = new PdfDictionary();
Array.Copy(pk, 0, outc, 0, pk.Length);
dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
sap.Close(dic2);
fs.Close();
st.Close();
reader.Close();
И все работает, если средствами NET подписание. Связки CryptSignMessage и работы по встраиванию а PDF с iTextSharp ни в одном Гугле не нашел. Решил поступить на "авось", посмотрел, что массив данных получается выше и подсовывается: Код:ContentInfo contentInfo = new ContentInfo(ms.ToArray());
и далее используются методы .NET влез со своим CryptSignMessage byte[] data = ms.ToArray();вместо: ContentInfo contentInfo = new ContentInfo(ms.ToArray()); и дальше пошел подписывать byte[] data Код:
IntPtr[] rgpbToBeSigned = new IntPtr[1];
int[] rgcbToBeSigned = new int[1];
CRYPT_SIGN_MESSAGE_PARA SignPara = new CRYPT_SIGN_MESSAGE_PARA();
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(data[0]) * data.Length);
Marshal.Copy(data, 0, buffer, data.Length);
rgpbToBeSigned[0] = buffer;
rgcbToBeSigned[0] = 1; // 1 или 0 вроде ни на что не влияла
SignPara.cbSize = Marshal.SizeOf(SignPara);
SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
SignPara.pSigningCert = pCertContext;//signingCert.Handle;
SignPara.HashAlgorithm.pszObjId = "1.2.643.7.1.1.2.2";
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.HashAlgorithm.Parameters.pbData = null;
SignPara.pvHashAuxInfo = IntPtr.Zero;
//добавляю только свой сертификат без цепочки
SignPara.cMsgCert = 1;
GCHandle GC = GCHandle.Alloc(pCertContext, GCHandleType.Pinned);
SignPara.rgpMsgCert = GC.AddrOfPinnedObject();
GC.Free();
SignPara.cMsgCrl = 0;
SignPara.cAuthAttr = 0;
SignPara.dwInnerContentType = 0;
SignPara.cUnauthAttr = 0;
SignPara.dwFlags = 0;
SignPara.pvHashAuxInfo = IntPtr.Zero;
SignPara.rgAuthAttr = IntPtr.Zero;
Int32 cbSignedMessageBlob = 0;
Byte[] pbSignedMessageBlob = null;
int signSize = 0;
//определяю размер
CryptSignMessage(ref SignPara, true, 1, rgpbToBeSigned, rgcbToBeSigned, null, ref signSize);
pbSignedMessageBlob = new Byte[signSize];
//получаю pbSignedMessageBlob
CryptSignMessage(ref SignPara, true, 1, rgpbToBeSigned, rgcbToBeSigned, pbSignedMessageBlob, ref signSize);
Далее, получив pbSignedMessageBlob и считая его подписанным и закодированным хешем я дальше засовываю его в PDF: pk = pbSignedMessageBlob;Код:byte[] outc = new byte[intCSize];
PdfDictionary dic2 = new PdfDictionary();
Array.Copy(pk, 0, outc, 0, pk.Length);
dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
sap.Close(dic2);
fs.Close();
st.Close();
reader.Close();
На выходе имею файл PDF. В нем имеется сертификат. Но все остальное пишет: Подпись не определена Подпись недействительна Подпись сделана в формате CADES BES Сертификат ненадежный Документ был изменен или поврежден с момента подписания Когда же подписываю signedCms.ComputeSignature все проходит на отлично. Подскажите, в какую сторону нужно смотреть дальше. Отредактировано пользователем 21 апреля 2020 г. 15:23:33(UTC)
| Причина: Не указана
|