Код, который вам нужен, очевидно, аналогичен коду, который метод iText AcroFields.VerifySignature
выполняет при создании объекта PdfPKCS7
, представляющего данную подпись. Так как iText является открытым исходным кодом, вы можете просто скопировать этот код так, как вам нужно!
Например,
Я не знаю, как прочитать подпись SM2 из поля формы PDF.
blockquote>
AcroFields.VerifySignature
начинается так:virtual public PdfPKCS7 VerifySignature(String name) { PdfDictionary v = GetSignatureDictionary(name); if (v == null) return null; PdfName sub = v.GetAsName(PdfName.SUBFILTER); PdfString contents = v.GetAsString(PdfName.CONTENTS); PdfPKCS7 pk = null; if (sub.Equals(PdfName.ADBE_X509_RSA_SHA1)) { PdfString cert = v.GetAsString(PdfName.CERT); if (cert == null) cert = v.GetAsArray(PdfName.CERT).GetAsString(0); pk = new PdfPKCS7(contents.GetOriginalBytes(), cert.GetBytes()); } else pk = new PdfPKCS7(contents.GetOriginalBytes(), sub);
Таким образом, необходимый код для извлечения встроенного объекта подписи выглядит следующим образом
AcroFields acroFields = reader.AcroFields; PdfDictionary v = acroFields.GetSignatureDictionary(name); if (v != null) { PdfString contents = v.GetAsString(PdfName.CONTENTS); byte[] embeddedSignatureObjectBytes = contents.GetOriginalBytes(); [... process embeddedSignatureObjectBytes ...] }
Осторожно: так как Содержимое строка дополняется нулями,
embeddedSignatureObjectBytes
байтов после того, как фактический объект подписи будет содержать хвост 0x00 байтов.Я не знаю, как получить подписанные данные о происхождении
blockquote>
AcroFields.VerifySignature
продолжается так:UpdateByteRange(pk, v);
AcroFields.UpdateByteRange
реализовано так this:private void UpdateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) { PdfArray b = v.GetAsArray(PdfName.BYTERANGE); RandomAccessFileOrArray rf = reader.SafeFile; Stream rg = null; try { rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), b.AsLongArray())); byte[] buf = new byte[8192]; int rd; while ((rd = rg.Read(buf, 0, buf.Length)) > 0) { pkcs7.Update(buf, 0, rd); } } finally { if (rg != null) rg.Close(); } }
Таким образом, необходимый код для чтения байтов подписанного документа выглядит следующим образом
AcroFields acroFields = reader.AcroFields; PdfDictionary v = acroFields.GetSignatureDictionary(name); if (v != null) { PdfArray b = v.GetAsArray(PdfName.BYTERANGE); RandomAccessFileOrArray rf = reader.SafeFile; Stream rg = null; try { rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), b.AsLongArray())); [... process the signed data in the Stream rg ...] } finally { if (rg != null) rg.Close(); } }
Можно ли установить это программно в Наборах controller:-
HttpContext.Current.Server.ScriptTimeout = 300;
тайм-аут к 5 минутам вместо значения по умолчанию 110 секунд (что нечетное значение по умолчанию?)