private String calculateSigningContent(X509Certificate2 cert) { byte[] sh = null; try { Org.BouncyCastle.X509.X509Certificate[] chain = GetCertChain(cert); sgn = new PdfPKCS7(null, chain, "SHA-256", true); hashValue = HashFile(sap.GetRangeStream()); List <ICrlClient> crlList = new List <ICrlClient>(); crlList.Add(new CrlClientOnline(chain)); ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < chain.Length) { crlBytes = MakeSignature.ProcessCrl(chain[i++], null); } sh = sgn.getAuthenticatedAttributeBytes(hashValue, null, crlBytes /*crlbyte*/, CryptoStandard.CADES); } catch (Exception ex) { if (document != null) { document.Close(); } if (pdfStamper != null) { pdfStamper.Close(); } throw new Exception("getHash : " + ex.Message, ex); } return(System.Convert.ToBase64String(sh)); }
/** * Sign the document using an external container, usually a PKCS7. The signature is fully composed * externally, iText will just put the container inside the document. * @param sap the PdfSignatureAppearance * @param externalSignatureContainer the interface providing the actual signing * @param estimatedSize the reserved size for the signature * @throws GeneralSecurityException * @throws IOException * @throws DocumentException */ public static void SignExternalContainer(PdfSignatureAppearance sap, IExternalSignatureContainer externalSignatureContainer, int estimatedSize) { PdfSignature dic = new PdfSignature(null, null); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.SignatureCreator = sap.SignatureCreator; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this externalSignatureContainer.ModifySigningDictionary(dic); sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); byte[] encodedSig = externalSignatureContainer.Sign(data); if (estimatedSize < encodedSig.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.SetVisibleSignature(new Rectangle(0,0,0,0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary<PdfName,int> exc = new Dictionary<PdfName,int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = DigestUtilities.GetDigest(tsa.GetDigestAlgorithm()); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken = tsa.GetTimeStampToken(tsImprint); if (contentEstimated + 2 < tsToken.Length) throw new Exception("Not enough space"); byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
public string GenerateHash() { string Reason = "Motivo"; string Location = "Localização"; string Contact = "Contato"; string signatureFieldName = null; appearance.SetVisibleSignature(new Rectangle(500, 150, 400, 200), 1, signatureFieldName); appearance.SignDate = DateTime.Now; appearance.Reason = Reason; appearance.Location = Location; appearance.Contact = Contact; StringBuilder buf = new StringBuilder(); buf.Append("Digitally signed by"); buf.Append("\n"); buf.Append(userName); buf.Append("\n"); buf.Append("Date: " + appearance.SignDate); appearance.Layer2Text = buf.ToString(); appearance.Acro6Layers = true; appearance.CertificationLevel = 0; PdfSignature dic = GeneratePdfSignature(); appearance.CryptoDictionary = dic; Dictionary <PdfName, int> exclusionSizes = new Dictionary <PdfName, int>(); exclusionSizes.Add(PdfName.CONTENTS, (RESERVED_SPACE_SIGNATURE * 2) + 2); appearance.PreClose(exclusionSizes); HashAlgorithm sha = new SHA256CryptoServiceProvider(); Stream s = appearance.GetRangeStream(); int read = 0; byte[] buff = new byte[0x2000]; while ((read = s.Read(buff, 0, 0x2000)) > 0) { sha.TransformBlock(buff, 0, read, buff, 0); } sha.TransformFinalBlock(buff, 0, 0); StringBuilder hex = new StringBuilder(sha.Hash.Length * 2); foreach (byte b in sha.Hash) { hex.AppendFormat("{0:x2}", b); } return(hex.ToString()); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL5); sap.SetVisibleSignature(new Rectangle(0, 0, 0, 0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = tsa.GetMessageDigest(); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken; try { tsToken = tsa.GetTimeStampToken(tsImprint); } catch (Exception e) { throw new GeneralSecurityException(e.Message); } //TODO jbonilla Validar para el TSA de Certificado que devuelve un valor muy grande. if (contentEstimated + 2 < tsToken.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
//schimbare functie pentru iText private string generateHash() { appearance.SetVisibleSignature(new Rectangle(500, 150, 400, 200), 1, "signature"); appearance.SignDate = DateTime.Now; appearance.Reason = "Test Licenta"; appearance.Location = "Bucuresti"; appearance.Contact = "mta"; StringBuilder buf = new StringBuilder(); buf.Append("Semnat digital de"); buf.Append("\n"); buf.Append(userName); buf.Append("\n"); buf.Append("Date: " + appearance.SignDate); appearance.Layer2Text = buf.ToString(); appearance.Acro6Layers = true; appearance.CertificationLevel = 0; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED) { Date = new PdfDate(appearance.SignDate), Name = userName }; dic.Reason = appearance.Reason; dic.Location = appearance.Location; dic.Contact = appearance.Contact; appearance.CryptoDictionary = dic; Dictionary <PdfName, int> exclusionSizes = new Dictionary <PdfName, int>(); exclusionSizes.Add(PdfName.CONTENTS, (csize * 2) + 2); appearance.PreClose(exclusionSizes); HashAlgorithm sha = new SHA256CryptoServiceProvider(); Stream s = appearance.GetRangeStream(); int read = 0; byte[] buff = new byte[0x2000]; while ((read = s.Read(buff, 0, 0x2000)) > 0) { sha.TransformBlock(buff, 0, read, buff, 0); } sha.TransformFinalBlock(buff, 0, 0); return(System.Convert.ToBase64String(sha.Hash)); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.SetVisibleSignature(new Rectangle(0, 0, 0, 0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = DigestUtilities.GetDigest(tsa.GetDigestAlgorithm()); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken = tsa.GetTimeStampToken(tsImprint); if (contentEstimated + 2 < tsToken.Length) { throw new Exception("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs a document with a PAdES-LTV Timestamp. The document is closed at the end. * @param sap the signature appearance * @param tsa the timestamp generator * @param signatureName the signature name or null to have a name generated * automatically * @throws Exception */ public static void Timestamp(PdfSignatureAppearance sap, ITSAClient tsa, String signatureName) { int contentEstimated = tsa.GetTokenSizeEstimate(); sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL5); sap.SetVisibleSignature(new Rectangle(0,0,0,0), 1, signatureName); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ETSI_RFC3161); dic.Put(PdfName.TYPE, PdfName.DOCTIMESTAMP); sap.CryptoDictionary = dic; Dictionary<PdfName,int> exc = new Dictionary<PdfName,int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); IDigest messageDigest = tsa.GetMessageDigest(); byte[] buf = new byte[4096]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] tsImprint = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(tsImprint, 0); byte[] tsToken; try { tsToken = tsa.GetTimeStampToken(tsImprint); } catch(Exception e) { throw new GeneralSecurityException(e.Message); } //TODO jbonilla Validar para el TSA de Certificado que devuelve un valor muy grande. if (contentEstimated + 2 < tsToken.Length) throw new IOException("Not enough space"); byte[] paddedSig = new byte[contentEstimated]; System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Closes the document. No more content can be written after the * document is closed. * <p> * If closing a signed document with an external signature the closing must be done * in the <CODE>PdfSignatureAppearance</CODE> instance. * @throws DocumentException on error * @throws IOException on error */ public void Close() { if (stamper.closed) { return; } if (!hasSignature) { MergeVerification(); stamper.Close(moreInfo); return; } sigApp.PreClose(); PdfSigGenericPKCS sig = sigApp.SigStandard; PdfLiteral lit = (PdfLiteral)sig.Get(PdfName.CONTENTS); int totalBuf = (lit.PosLength - 2) / 2; byte[] buf = new byte[8192]; int n; Stream inp = sigApp.GetRangeStream(); while ((n = inp.Read(buf, 0, buf.Length)) > 0) { sig.Signer.Update(buf, 0, n); } buf = new byte[totalBuf]; byte[] bsig = sig.SignerContents; Array.Copy(bsig, 0, buf, 0, bsig.Length); PdfString str = new PdfString(buf); str.SetHexWriting(true); PdfDictionary dic = new PdfDictionary(); dic.Put(PdfName.CONTENTS, str); sigApp.Close(dic); stamper.reader.Close(); }
static void signPDF(string document) { //string certificate_dn = "C=RU, S=lenobl, L=spb, O=fil, OU=IT, CN=iks, E=iks@iks"; // Subject->Name string certificate_dn = "L=Санкт-Петербург, O=ООО Филберт, CN=iks, [email protected]"; X509Store store = new X509Store("My", StoreLocation.CurrentUser); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); X509Certificate2Collection found = store.Certificates.Find( X509FindType.FindBySubjectDistinguishedName, certificate_dn, true); if (found.Count == 0) { Console.Out.Write("Сертфикат [" + certificate_dn + "] не найден "); return; } if (found.Count > 1) { Console.WriteLine("Найдено более одного секретного ключа."); return; } X509Certificate2 certificate = found[0]; CryptoPro.Sharpei.Gost3410_2012_256CryptoServiceProvider cert_key = certificate.PrivateKey as CryptoPro.Sharpei.Gost3410_2012_256CryptoServiceProvider; var cspParameters = new CspParameters(); //копируем параметры csp из исходного контекста сертификата cspParameters.KeyContainerName = cert_key.CspKeyContainerInfo.KeyContainerName; cspParameters.ProviderType = cert_key.CspKeyContainerInfo.ProviderType; cspParameters.ProviderName = cert_key.CspKeyContainerInfo.ProviderName; cspParameters.Flags = cert_key.CspKeyContainerInfo.MachineKeyStore ? (CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore) : (CspProviderFlags.UseExistingKey); cspParameters.KeyPassword = new SecureString(); string pass = "******"; foreach (var c in pass) { cspParameters.KeyPassword.AppendChar(c); } //создаем новый контекст сертификат, поскольку исходный открыт readonly certificate = new X509Certificate2(certificate.RawData); //задаем криптопровайдер с установленным паролем certificate.PrivateKey = new CryptoPro.Sharpei.Gost3410_2012_256CryptoServiceProvider(cspParameters); /////////////////////////читаем файл /* * System.IO.StreamReader file = new System.IO.StreamReader("C:\\TEMP\\test.json"); * * string s = file.ReadToEnd(); * byte[] body = Encoding.Default.GetBytes(s); */ ///////////////////////////// PDF подпись //////////////////////////////////////////////// PdfReader reader = new PdfReader(document); string newSigned = Path.Combine(Path.GetDirectoryName(document) + @"\" + Path.GetFileNameWithoutExtension(document) + "_signed" + Path.GetExtension(document)); FileStream signedPDF = new FileStream(newSigned, FileMode.Create, FileAccess.ReadWrite); PdfStamper st = PdfStamper.CreateSignature(reader, signedPDF, '\0', null, true); PdfSignatureAppearance sap = st.SignatureAppearance; // Загружаем сертификат в объект iTextSharp X509CertificateParser parser = new X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { parser.ReadCertificate(certificate.RawData) }; sap.Certificate = parser.ReadCertificate(certificate.RawData); sap.Reason = "I like to sign"; sap.Location = "Universe"; sap.Acro6Layers = true; //sap.Render = PdfSignatureAppearance.SignatureRender.NameAndDescription; sap.SignDate = DateTime.Now; // Выбираем подходящий тип фильтра PdfName filterName = new PdfName("CryptoPro PDF"); // Создаем подпись PdfSignature dic = new PdfSignature(filterName, PdfName.ADBE_PKCS7_DETACHED); dic.Date = new PdfDate(sap.SignDate); dic.Name = "iks"; if (sap.Reason != null) { dic.Reason = sap.Reason; } if (sap.Location != null) { dic.Location = sap.Location; } sap.CryptoDictionary = dic; int intCSize = 4000; Dictionary <PdfName, int> hashtable = new Dictionary <PdfName, int>(); hashtable[PdfName.CONTENTS] = intCSize * 2 + 2; sap.PreClose(hashtable); Stream s = sap.GetRangeStream(); MemoryStream ss = new MemoryStream(); int read = 0; byte[] buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { ss.Write(buff, 0, read); } ////////////////////////////////////////// // Вычисляем подпись ContentInfo contentInfo = new ContentInfo(ss.ToArray()); SignedCms signedCms = new SignedCms(contentInfo, true); CmsSigner cmsSigner = new CmsSigner(certificate); signedCms.ComputeSignature(cmsSigner, false); byte[] pk = signedCms.Encode(); /* * // Помещаем подпись в документ * 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); */ Console.WriteLine(string.Format("Документ {0} успешно подписан на ключе {1} => {2}.", document, certificate.Subject, newSigned)); /* * System.IO.StreamWriter sw = null; * System.IO.FileStream fs = new System.IO.FileStream("C:\\TEMP\\test_json_signed.json", System.IO.FileMode.Append, System.IO.FileAccess.Write); * * * sw = new System.IO.StreamWriter(fs, Encoding.GetEncoding(1251)); * sw.WriteLine(Encoding.Default.GetString(pk)); * sw.Close(); * * fs.Dispose(); * fs.Close(); */ // Помещаем подпись в документ 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); ///////////////////////////////////////////////////////////////////////////// }
public static int Main(string[] args) { // Разбираем аргументы if (args.Length < 2) { Console.WriteLine("Pdf.Sign <document> <certificate-dn> [<key-container-password>]"); return(1); } string document = args[0]; string certificate_dn = args[1]; /* * // Извлечение клиентского сертификата из хранилища: * X509Store x509Store = new X509Store(StoreLocation.CurrentUser); * x509Store.Open(OpenFlags.ReadOnly); * var x509Certificate = x509Store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, * //"[email protected], CN=Sozonjuk Aleksandr Vasil'evich, OU=Department of information technologies, O=s3bank.ru, L=Moscow, S=Moscow, C=RU", * "[email protected], CN=S3Bank-Rostelecom Service, OU=IT Department, O=s3bank.ru, L=Moscow, S=Moscow, C=RU", * false)[0]; */ // Находим секретный ключ по сертификату в хранилище X509Store x509Store = new X509Store("My", StoreLocation.CurrentUser); x509Store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); X509Certificate2Collection found = x509Store.Certificates.Find( //X509FindType.FindByThumbprint, certificate_dn, true); X509FindType.FindBySubjectDistinguishedName, certificate_dn, true); if (found.Count == 0) { Console.WriteLine("Секретный ключ не найден."); return(1); } if (found.Count > 1) { Console.WriteLine("Найдено более одного секретного ключа."); return(1); } X509Certificate2 certificate = found[0]; if (args.Length > 2) { //set password. Пароль "0" //var cert_key = certificate.PrivateKey as Gost3410_2012_256CryptoServiceProvider; //Gost3410CryptoServiceProvider; var cert_key = certificate.PrivateKey as Gost3410CryptoServiceProvider; if (null != cert_key) { var cspParameters = new CspParameters(); //копируем параметры csp из исходного контекста сертификата cspParameters.KeyContainerName = cert_key.CspKeyContainerInfo.KeyContainerName; cspParameters.ProviderType = cert_key.CspKeyContainerInfo.ProviderType; cspParameters.ProviderName = cert_key.CspKeyContainerInfo.ProviderName; cspParameters.Flags = cert_key.CspKeyContainerInfo.MachineKeyStore ? (CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore) : (CspProviderFlags.UseExistingKey); cspParameters.KeyPassword = new SecureString(); foreach (var c in args[2]) { cspParameters.KeyPassword.AppendChar(c); } //создаем новый контекст сертификат, поскольку исходный открыт readonly certificate = new X509Certificate2(certificate.RawData); //задаем криптопровайдер с установленным паролем //certificate.PrivateKey = new Gost3410_2012_256CryptoServiceProvider(cspParameters); certificate.PrivateKey = new Gost3410CryptoServiceProvider(cspParameters); } } PdfReader reader = new PdfReader(document); PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(document.Replace(".pdf", "") + "_signed.pdf", FileMode.Create, FileAccess.Write), '\0'); PdfSignatureAppearance sap = st.SignatureAppearance; // Загружаем сертификат в объект iTextSharp X509CertificateParser parser = new X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { parser.ReadCertificate(certificate.RawData) }; sap.Certificate = parser.ReadCertificate(certificate.RawData); sap.Reason = "Первый сценарий"; sap.Location = "Universe"; sap.Acro6Layers = true; //sap.Render = PdfSignatureAppearance.SignatureRender.NameAndDescription; sap.SignDate = DateTime.Now; // Выбираем подходящий тип фильтра PdfName filterName = new PdfName("CryptoPro PDF"); // Создаем подпись PdfSignature dic = new PdfSignature(filterName, PdfName.ADBE_PKCS7_DETACHED); dic.Date = new PdfDate(sap.SignDate); dic.Name = "PdfPKCS7 signature"; if (sap.Reason != null) { dic.Reason = sap.Reason; } if (sap.Location != null) { dic.Location = sap.Location; } sap.CryptoDictionary = dic; int intCSize = 4000; Dictionary <PdfName, int> hashtable = new Dictionary <PdfName, int>(); hashtable[PdfName.CONTENTS] = intCSize * 2 + 2; sap.PreClose(hashtable); Stream s = sap.GetRangeStream(); MemoryStream ss = new MemoryStream(); int read = 0; byte[] buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { ss.Write(buff, 0, read); } // Вычисляем подпись ContentInfo contentInfo = new ContentInfo(ss.ToArray()); SignedCms signedCms = new SignedCms(contentInfo, true); CmsSigner cmsSigner = new CmsSigner(certificate); signedCms.ComputeSignature(cmsSigner, false); byte[] pk = signedCms.Encode(); // Помещаем подпись в документ 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); Console.WriteLine("Документ {0} успешно подписан на ключе {1} => {2}.", document, certificate.Subject, document + "_signed.pdf"); return(0); }
/** * Signs the document using the detached mode, CMS or CAdES equivalent. * @param sap the PdfSignatureAppearance * @param externalSignature the interface providing the actual signing * @param chain the certificate chain * @param crlList the CRL list * @param ocspClient the OCSP client * @param tsaClient the Timestamp client * @param provider the provider or null * @param estimatedSize the reserved size for the signature. It will be estimated if 0 * @param cades true to sign CAdES equivalent PAdES-BES, false to sign CMS * @throws DocumentException * @throws IOException * @throws GeneralSecurityException * @throws NoSuchAlgorithmException * @throws Exception */ public static void SignDetached(PdfSignatureAppearance sap, IExternalSignature externalSignature, ICollection <X509Certificate> chain, ICollection <ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype) { List <X509Certificate> certa = new List <X509Certificate>(chain); ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < certa.Count) { crlBytes = ProcessCrl(certa[i++], crlList); } if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) { estimatedSize += 4192; } if (tsaClient != null) { estimatedSize += 4192; } } sap.Certificate = certa[0]; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, sigtype == CryptoStandard.CADES ? PdfName.ETSI_CADES_DETACHED : PdfName.ADBE_PKCS7_DETACHED); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Count >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded(certa[0], certa[1], null); } byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize + 2 < encodedSig.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
private static void DoSignPdfFile(PdfStamper stamper, ConversionProfile profile, JobPasswords jobPasswords) { Signature signing = profile.PdfSettings.Signature; if (!signing.Enabled) //Leave without signing { return; } Logger.Debug("Start signing file."); signing.CertificateFile = Path.GetFullPath(signing.CertificateFile); if (string.IsNullOrEmpty(jobPasswords.PdfSignaturePassword)) { Logger.Error("Launched signing without certification password."); throw new ProcessingException("Launched signing without certification password.", 12204); } if (IsValidCertificatePassword(signing.CertificateFile, jobPasswords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The password for certificate '" + signing.CertificateFile + "' is wrong."); throw new ProcessingException("Canceled signing. The password for certificate '" + signing.CertificateFile + "' is wrong.", 12200); } if (CertificateHasPrivateKey(signing.CertificateFile, jobPasswords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The certificate '" + signing.CertificateFile + "' has no private key."); throw new ProcessingException( "Canceled signing. The certificate '" + signing.CertificateFile + "' has no private key.", 12201); } var fsCert = new FileStream(signing.CertificateFile, FileMode.Open); var ks = new Pkcs12Store(fsCert, jobPasswords.PdfSignaturePassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al) && ks.GetKey(al).Key.IsPrivate) { alias = al; break; } } fsCert.Close(); ICipherParameters pk = ks.GetKey(alias).Key; X509CertificateEntry[] x = ks.GetCertificateChain(alias); var chain = new X509Certificate[x.Length]; for (int k = 0; k < x.Length; ++k) { chain[k] = x[k].Certificate; } ITSAClient tsc = null; if (!string.IsNullOrEmpty(signing.TimeServerUrl.Trim())) { if (!signing.TimeServerIsSecured) { tsc = new TSAClientBouncyCastle(signing.TimeServerUrl); } else { tsc = new TSAClientBouncyCastle(signing.TimeServerUrl, signing.TimeServerLoginName, signing.TimeServerPassword); } } PdfSignatureAppearance psa = stamper.SignatureAppearance; if (tsc == null) { psa.SetCrypto(pk, chain, null, PdfSignatureAppearance.WINCER_SIGNED); } else { psa.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED); } if (!profile.PdfSettings.Signature.AllowMultiSigning) { //Lock PDF, except for annotations and form filling (irrelevant for PDFCreator) psa.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS; } psa.Reason = signing.SignReason; psa.Contact = signing.SignContact; psa.Location = signing.SignLocation; if (signing.DisplaySignatureInDocument) { int signPage = SignPageNr(stamper, signing); psa.SetVisibleSignature(new Rectangle(signing.LeftX, signing.LeftY, signing.RightX, signing.RightY), signPage, null); } var dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = psa.Reason; dic.Location = psa.Location; dic.Contact = psa.Contact; dic.Date = new PdfDate(psa.SignDate); psa.CryptoDictionary = dic; const int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) var exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; psa.PreClose(exc); const string hashAlgorithm = "SHA1"; //Always use HashAlgorithm "SHA1" var sgn = new PdfPKCS7(pk, chain, null, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = psa.GetRangeStream(); var buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } var hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); byte[] ocsp = null; if (chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(chain[0]); if (!string.IsNullOrEmpty(url)) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); } } DateTime cal = psa.SignDate; byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); var paddedSig = new byte[contentEstimated]; if (tsc != null) { byte[] encodedSigTsa = null; try { encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp); Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); } catch (Exception ex) { throw new ProcessingException( ex.GetType() + " while connecting to timeserver (can't connect to timeserver): " + ex.Message, 12205); } if (contentEstimated + 2 < encodedSigTsa.Length) { throw new ProcessingException( "Not enough space for signature", 12202); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { throw new ProcessingException("Not enough space for signature", 12203); } } var dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); psa.Close(dic2); }
protected override byte[] SignX509(byte[] pdf, bool detached) { _chain = GetChain(); using (PdfReader reader = new PdfReader(pdf)) { using (MemoryStream result = new MemoryStream()) { using (PdfStamper stp = PdfStamper.CreateSignature(reader, result, '\0', null, true)) { PdfSignatureAppearance sap = stp.SignatureAppearance; sap.Certificate = _chain; var certificateInfo = new Juschubut.PdfDigitalSign.CertificateInfo(this.Certificate); this.OnPrepareSignatureEvent(certificateInfo); sap.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC; PdfSignature dic = null; if (detached) { dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); } else { dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); } dic.Name = certificateInfo.CN; this.AddSignature(reader, sap, certificateInfo); sap.CryptoDictionary = dic; int csize = detached ? 10000 : 4000; var exc = new Dictionary <PdfName, int>(); exc.Add(PdfName.CONTENTS, csize * 2 + 2); sap.PreClose(exc); byte[] pk; using (Stream stream = sap.GetRangeStream()) { pk = this.SignMessage(stream, detached); } byte[] outc = new byte[csize]; PdfDictionary dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); sap.Close(dic2); outc = null; pk = null; return(result.ToArray()); } } } }
/// <summary> /// Prepare the data needed for digital signature. Unfortunately /// CAPICOM's client-side implementation both hashes **AND** signs /// passed in data instead of signing data already hashed, so the /// **entire** PDF content bytes are needed. /// </summary> /// <param name="pdfIn">PDF file contents</param> /// <returns> /// Base64 encoded PDF content bytes client will sign. /// </returns> public string PreSign(byte[] pdfIn) { byte[] pdfRawContent = null; bool isOdd = true; var timeStamp = DateTime.Now; var pdfSignature = new PdfSignature( PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED ); pdfSignature.Date = new PdfDate(timeStamp); var exclusionSizes = new Dictionary <PdfName, int>(); exclusionSizes.Add(PdfName.CONTENTS, EXCLUSION_BUFFER * 2 + 2); PdfReader reader = null; int? signedFields = null; try { var cert = new WebCertificateReader().GetSigningCertificate(); do { ++DataReadCount; reader = new PdfReader(pdfIn); _acroFieldsWorker = new AcroFieldsReader(reader.AcroFields); signedFields = signedFields ?? _acroFieldsWorker.SignedFields(); _memoryStream = new MemoryStream(); var stamper = signedFields == 0 ? PdfStamper.CreateSignature(reader, _memoryStream, '\0') : PdfStamper.CreateSignature(reader, _memoryStream, '\0', null, true) ; _signatureAppearance = stamper.SignatureAppearance; InitSignatureField(stamper); pdfSignature.Reason = Reason; _signatureAppearance.Certificate = cert; _signatureAppearance.SignDate = timeStamp; _signatureAppearance.CryptoDictionary = pdfSignature; _signatureAppearance.PreClose(exclusionSizes); using (Stream sapStream = _signatureAppearance.GetRangeStream()) { using (var ms = new MemoryStream()) { sapStream.CopyTo(ms); pdfRawContent = ms.ToArray(); } // pdfRawContent = StreamHandler.ReadAllBytes(sapStream); // fix CAPICOM's broken implemetation: signature // invalid if sapStream.Length is **ODD** if ((pdfRawContent.Length % 2) == 0) { isOdd = false; } else { // Reason += '\0'; Reason += " "; } DataSize = sapStream.Length; } // sanity check if (DataReadCount > 200) { throw new InvalidOperationException("DataReadCount"); } } while (isOdd); } catch { throw; } finally { HttpContext.Current.Session[InstanceLookupKey] = this; if (reader != null) { reader.Dispose(); } } return(Convert.ToBase64String(pdfRawContent)); }
public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption enc) { byte[] ownerPassword = null; if (!string.IsNullOrEmpty(enc.OwnerPwd)) { ownerPassword = DocWriter.GetISOBytes(enc.OwnerPwd); } PdfReader reader = new PdfReader(this.inputPDF, ownerPassword); FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write); PdfStamper st; if (this.myCert == null) //No signature just write meta-data and quit { st = new PdfStamper(reader, fs); } else { st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi); } if (encrypt && enc != null) { enc.Encrypt(st); } //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY); st.MoreInfo = this.metadata.getMetaData(); st.XmpMetadata = this.metadata.getStreamedMetaData(); if (this.myCert == null) //No signature just write meta-data and quit { st.Close(); return; } PdfSignatureAppearance sap = st.SignatureAppearance; //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED); sap.Reason = sigAP.SigReason; sap.Contact = sigAP.SigContact; sap.Location = sigAP.SigLocation; if (sigAP.Visible) { iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page); sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData); sap.Layer2Text = sigAP.CustomText; sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null); } // Remove yellow question mark (green check mark is still used though) //sap.GetLayer(1); // The first signature is a certification //if (!sigAP.Multi) //{ // //sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; // sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING; //} PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA-256", false); IDigest messageDigest = DigestUtilities.GetDigest("SHA-256"); // change for itextsharp-all-5.2.1 Stream data = sap.GetRangeStream(); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (this.myCert.Chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]); if (url != null && url.Length > 0) { //ocsp = new OcspClientBouncyCastle(this.myCert.Chain[0], this.myCert.Chain[1], url).GetEncoded(); // change for itextsharp-all-5.2.1 ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url); } } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] paddedSig = new byte[contentEstimated]; if (this.myCert.Tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp); System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) { throw new Exception("Not enough space for signature"); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { throw new Exception("Not enough space for signature"); } } PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); //// Lock all fields after signing (backport from iText 5.4.4) - wrong - doesn't work //PdfDictionary lockDic = new PdfDictionary(new PdfName("SigFieldLock")); //lockDic.Put(PdfName.ACTION, new PdfName("All")); //lockDic.Put(PdfName.P, new PdfNumber(1)); //dic2.Put(PdfName.LOCK, lockDic); sap.Close(dic2); //st.Close(); }
public void Button3Click(object sender, System.EventArgs e) { if (inputBox.Text != null) { string filePDF = inputBox.Text; try { X509Certificate2 card = GetCertificate(); Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(card.RawData) }; //ricreo il percorso con il nome del novo file string file = filePDF.Substring(1 + filePDF.LastIndexOf(@"\")).ToLowerInvariant(); string NuovoFile = filePDF.Substring(0, filePDF.LastIndexOf(@"\") + 1) + file.Substring(0, file.LastIndexOf(".")) + "_firmato.pdf".ToLowerInvariant(); PdfReader reader = new PdfReader(filePDF); PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(NuovoFile, FileMode.Create), '\0', null, multiSigChkBx.Checked); PdfSignatureAppearance sap = stp.SignatureAppearance; if (tsaCbx.Checked) { ITSAClient tsc = new TSAClientBouncyCastle(TSAUrlTextBox.Text, tsaLogin.Text, tsaPwd.Text); } if (SigVisible.Checked) { sap.Reason = cbRagioneSingolo.Text; sap.Contact = Contacttext.Text; sap.Location = Locationtext.Text; if (sigImgBox.Image != null) { MemoryStream ms = new MemoryStream(); sigImgBox.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); sap.Image = ms.ToArray() == null ? null : iTextSharp.text.Image.GetInstance(ms.ToArray()); ms.Close(); } sap.SetVisibleSignature(new iTextSharp.text.Rectangle((float)sigPosX.Value, (float)sigPosY.Value, (float)sigPosX.Value + (float)sigWidth.Value, (float)sigPosY.Value + (float)sigHeight.Value), Convert.ToInt32(numberOfPagesUpDown.Value), null); } sap.SignDate = DateTime.Now; sap.SetCrypto(null, chain, null, null); sap.Acro6Layers = true; sap.Render = PdfSignatureAppearance.SignatureRender.Description; //.NameAndDescription; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic.Date = new PdfDate(sap.SignDate); dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); if (sap.Reason != null) { dic.Reason = sap.Reason; } if (sap.Location != null) { dic.Location = sap.Location; } if (sap.Contact != null) { dic.Contact = sap.Contact; } sap.CryptoDictionary = dic; int contentEstimated = 15000; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); IDigest messageDigest = DigestUtilities.GetDigest("SHA256"); //add Stream s = sap.GetRangeStream(); MemoryStream ss = new MemoryStream(); int read = 0; byte[] buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { ss.Write(buff, 0, read); messageDigest.BlockUpdate(buff, 0, read); //add } //-------------------------------------------- byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(chain[0]); if (url != null && url.Length > 0) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); MessageBox.Show(ocsp.ToString()); } } //------------------------------------------------------------------- //TEST TIMESTAMP CON BOUNCYCASTLE //------------------------------------------------------------------- /* * TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); * // Dummy request * TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha1, hash, BigInteger.ValueOf(100)); * byte[] reqData = request.GetEncoded(); * HttpWebRequest httpReq = (HttpWebRequest) WebRequest.Create("http://localhost:8080/signserver/process?workerId=1"); * httpReq.Method = "POST"; * httpReq.ContentType = "application/timestamp-query"; * httpReq.ContentLength = reqData.Length; * // Write the request content * Stream reqStream = httpReq.GetRequestStream(); * reqStream.Write(reqData, 0, reqData.Length); * reqStream.Close(); * HttpWebResponse httpResp = (HttpWebResponse) httpReq.GetResponse(); * // Read the response * Stream respStream = new BufferedStream(httpResp.GetResponseStream()); * TimeStampResponse response = new TimeStampResponse(respStream); * respStream.Close(); * //MessageBox.Show(response.TimeStampToken.TimeStampInfo.GenTime.ToString()); */ //------------------------------------------------------------------- //TEST TIMESTAMP CON BOUNCYCASTLE //------------------------------------------------------------------- //===================================QUI FIRMO byte[] pk; if (tsaCbx.Checked) { pk = SignMsg(ss.ToArray(), card, true, tsaCbx.Checked, TSAUrlTextBox.Text, tsaLogin.Text, tsaPwd.Text); } else { pk = SignMsg(ss.ToArray(), card, true, tsaCbx.Checked, "", "", ""); } //-------------------------------------------- byte[] outc = new byte[contentEstimated]; PdfDictionary dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); sap.Close(dic2); MessageBox.Show("File firmato correttamente", "Operazione Completata"); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } }
private MemoryStream Assinar2(MemoryStream ArquivoOrigem, X509Certificate2 cert, ref byte[] pkcs7) { this.card = cert; X509CertificateParser x509CertificateParser = new X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] array = new Org.BouncyCastle.X509.X509Certificate[] { x509CertificateParser.ReadCertificate(this.card.RawData) }; PdfReader reader = new PdfReader(ArquivoOrigem); MemoryStream memoryStream = new MemoryStream(); PdfStamper pdfStamper = PdfStamper.CreateSignature(reader, memoryStream, '\0', null, true); PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance; signatureAppearance.SetCrypto(null, array, null, PdfSignatureAppearance.SELF_SIGNED); signatureAppearance.Reason = this.proposito; signatureAppearance.Contact = this.contato; signatureAppearance.Location = this.localizacao; signatureAppearance.CryptoDictionary = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")) { Reason = signatureAppearance.Reason, Location = signatureAppearance.Location, Contact = signatureAppearance.Contact, Date = new PdfDate(signatureAppearance.SignDate) }; int num = 15000; Dictionary <PdfName, int> dictionary = new Dictionary <PdfName, int>(); dictionary[PdfName.CONTENTS] = num * 2 + 2; signatureAppearance.PreClose(dictionary); //PdfPKCS7 pdfPKCS = new PdfPKCS7(null, array, null, "SHA1", false); PdfPKCS7 pdfPKCS = new PdfPKCS7(null, array, null, "MD5", false); IDigest digest = DigestUtilities.GetDigest("MD5"); Stream rangeStream = signatureAppearance.GetRangeStream(); byte[] array2 = new byte[8192]; int length; while ((length = rangeStream.Read(array2, 0, array2.Length)) > 0) { digest.BlockUpdate(array2, 0, length); } byte[] array3 = new byte[digest.GetDigestSize()]; digest.DoFinal(array3, 0); DateTime now = DateTime.Now; byte[] ocsp = null; if (array.Length >= 2) { string oCSPURL = PdfPKCS7.GetOCSPURL(array[0]); if (oCSPURL != null && oCSPURL.Length > 0) { ocsp = new OcspClientBouncyCastle().GetEncoded(array[0], array[1], oCSPURL); } } byte[] authenticatedAttributeBytes = pdfPKCS.GetAuthenticatedAttributeBytes(array3, now, ocsp); byte[] digest2 = Assinar.SignSHA1withRSA(this.card, authenticatedAttributeBytes); pdfPKCS.SetExternalDigest(digest2, array3, "RSA"); byte[] array4 = new byte[num]; byte[] encodedPKCS = pdfPKCS.GetEncodedPKCS7(array3, now, null, ocsp); pkcs7 = encodedPKCS; Array.Copy(encodedPKCS, 0, array4, 0, encodedPKCS.Length); if (num + 2 < encodedPKCS.Length) { throw new ApplicationException("Não há espaço suficiente para assinatura."); } PdfDictionary pdfDictionary = new PdfDictionary(); pdfDictionary.Put(PdfName.CONTENTS, new PdfString(array4).SetHexWriting(true)); signatureAppearance.Close(pdfDictionary); //pdfStamper. return(memoryStream); }
/** * Sign the document using an external container, usually a PKCS7. The signature is fully composed * externally, iText will just put the container inside the document. * @param sap the PdfSignatureAppearance * @param externalSignatureContainer the interface providing the actual signing * @param estimatedSize the reserved size for the signature * @throws GeneralSecurityException * @throws IOException * @throws DocumentException */ public static void SignExternalContainer(PdfSignatureAppearance sap, IExternalSignatureContainer externalSignatureContainer, int estimatedSize) { PdfSignature dic = new PdfSignature(null, null); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.SignatureCreator = sap.SignatureCreator; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this externalSignatureContainer.ModifySigningDictionary(dic); sap.CryptoDictionary = dic; Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); Stream data = sap.GetRangeStream(); byte[] encodedSig = externalSignatureContainer.Sign(data); if (estimatedSize < encodedSig.Length) throw new IOException("Not enough space"); byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
/** * Signs the document using the detached mode, CMS or CAdES equivalent. * @param sap the PdfSignatureAppearance * @param externalSignature the interface providing the actual signing * @param chain the certificate chain * @param crlList the CRL list * @param ocspClient the OCSP client * @param tsaClient the Timestamp client * @param provider the provider or null * @param estimatedSize the reserved size for the signature. It will be estimated if 0 * @param cades true to sign CAdES equivalent PAdES-BES, false to sign CMS * @throws DocumentException * @throws IOException * @throws GeneralSecurityException * @throws NoSuchAlgorithmException * @throws Exception */ public static void SignDetached(PdfSignatureAppearance sap, IExternalSignature externalSignature, ICollection<X509Certificate> chain, ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype) { List<X509Certificate> certa = new List<X509Certificate>(chain); ICollection<byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < certa.Count) crlBytes = ProcessCrl(certa[i++], crlList); if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) estimatedSize += 4192; if (tsaClient != null) estimatedSize += 4192; } sap.Certificate = certa[0]; if(sigtype == CryptoStandard.CADES) sap.AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, sigtype == CryptoStandard.CADES ? PdfName.ETSI_CADES_DETACHED : PdfName.ADBE_PKCS7_DETACHED); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.SignatureCreator = sap.SignatureCreator; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this sap.CryptoDictionary = dic; Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Count >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded(certa[0], certa[1], null); } byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize < encodedSig.Length) throw new IOException("Not enough space"); byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
private ActionResult SignPdfFile(PdfStamper stamper, IJob job) { Signing s = job.Profile.PdfSettings.Signing; //Leave without signing //WEG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (!s.Enable) { if (stamper != null) { stamper.Close(); return(new ActionResult()); } Logger.Error("Could not create Stamper for Encryption, without Signing"); return(new ActionResult(ActionId, 104)); } //Continue for Signing s.CertificationFile = Path.GetFullPath(s.CertificationFile); if (IsValidCertificatePassword(s.CertificationFile, job.Passwords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The password for certificate '" + s.CertificationFile + "' is wrong."); stamper.Close(); return(new ActionResult(ActionId, 105)); } if (CertificateHasPrivateKey(s.CertificationFile, job.Passwords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The certificate '" + s.CertificationFile + "' has no private key."); stamper.Close(); return(new ActionResult(ActionId, 106)); } var fsCert = new FileStream(s.CertificationFile, FileMode.Open); var ks = new Pkcs12Store(fsCert, job.Passwords.PdfSignaturePassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al) && ks.GetKey(al).Key.IsPrivate) { alias = al; break; } } fsCert.Close(); ICipherParameters pk = ks.GetKey(alias).Key; X509CertificateEntry[] x = ks.GetCertificateChain(alias); var chain = new X509Certificate[x.Length]; for (int k = 0; k < x.Length; ++k) { chain[k] = x[k].Certificate; } ITSAClient tsc = null; if (s.TimeServerUrl.Trim() != "") //Timeserver with LogIn? { tsc = new TSAClientBouncyCastle(s.TimeServerUrl /*, TimeServerLogonName, TimeServerLogonPassword*/); } PdfSignatureAppearance sap = stamper.SignatureAppearance; if (tsc == null) { sap.SetCrypto(pk, chain, null, PdfSignatureAppearance.WINCER_SIGNED); } else { sap.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED); } sap.Reason = s.SignReason; sap.Contact = s.SignContact; sap.Location = s.SignLocation; if (s.DisplaySignatureInPdf) { int signPage = SignPageNr(job); sap.SetVisibleSignature(new Rectangle(s.LeftX, s.LeftY, s.RightX, s.RightY), signPage, null); } var dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; const int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) var exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); const string hashAlgorithm = "SHA1"; //Always use HashAlgorithm "SHA1" var sgn = new PdfPKCS7(pk, chain, null, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); var buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } var hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); byte[] ocsp = null; if (chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(chain[0]); if (!string.IsNullOrEmpty(url)) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); } } DateTime cal = sap.SignDate; byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); var paddedSig = new byte[contentEstimated]; if (tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp); Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) { Logger.Error("Not enough space for signature"); return(new ActionResult(ActionId, 107)); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { Logger.Error("Not enough space for signature"); return(new ActionResult(ActionId, 107)); } } var dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); return(new ActionResult()); }
public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption Enc) { PdfReader reader = new PdfReader(this.inputPDF); FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write); PdfStamper st; if (this.myCert == null) //No signature just write meta-data and quit { st = new PdfStamper(reader, fs); } else { st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi); } if (encrypt && Enc != null) { Enc.Encrypt(st); } //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY); st.MoreInfo = this.metadata.getMetaData(); st.XmpMetadata = this.metadata.getStreamedMetaData(); if (this.myCert == null) //No signature just write meta-data and quit { st.Close(); return; } PdfSignatureAppearance sap = st.SignatureAppearance; //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED); sap.Reason = sigAP.SigReason; sap.Contact = sigAP.SigContact; sap.Location = sigAP.SigLocation; if (sigAP.Visible) { iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page); sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData); sap.Layer2Text = sigAP.CustomText; sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null); } ///// PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA1", false); IDigest messageDigest = DigestUtilities.GetDigest("SHA1"); Stream data = sap.GetRangeStream(); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (this.myCert.Chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]); if (url != null && url.Length > 0) { ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url); } } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] paddedSig = new byte[contentEstimated]; if (this.myCert.Tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp); System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) { throw new Exception("Not enough space for signature"); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { throw new Exception("Not enough space for signature"); } } PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); ////// //st.Close(); }
public void SignDetached() { if (lb.Items.Count > 0) { try { X509Certificate2 card = GetCertificate(); Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(card.RawData) }; pb.Minimum = 0; pb.Maximum = lb.Items.Count; pb.Visible = true; foreach (object oFile in lb.Items) { string filePDF = oFile.ToString(); PdfReader reader = new PdfReader(filePDF); int Pagina = 1; int posX = 0, posY = 0, Altezza = 0, Larghezza = 0; //ricreo il percorso con il nome del nuovo file string file = filePDF.Substring(1 + filePDF.LastIndexOf(@"\")); string NuovoFile = filePDF.Substring(0, filePDF.LastIndexOf(@"\") + 1) + file.Substring(0, file.LastIndexOf(".")) + "_firmato.pdf"; PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(NuovoFile, FileMode.Create), '\0', null, multiSigChkBx.Checked); PdfSignatureAppearance sap = stp.SignatureAppearance; string nPagine = reader.NumberOfPages.ToString(); sap.Reason = cbRagione.Text + nPagine; sap.Contact = tbContatto.Text; sap.Location = tbLuogo.Text; if (cbFirmaVisibile.Checked == true) //firma visibile { if (rbNuovaPagina.Checked) //firma su nuova pagina { Pagina = reader.NumberOfPages + 1; stp.InsertPage(Pagina, reader.GetPageSize(1)); iTextSharp.text.Rectangle rect = reader.GetPageSize(Pagina); int w = Convert.ToInt32(rect.Width); int h = Convert.ToInt32(rect.Height); posX = 20; posY = h - 120; Larghezza = posX + 100; Altezza = posY + 100; } else if (rbVecchiaPagina.Checked) //firma su pagina esistente { int IndiceScelto = lbPosizioneFirma.SelectedIndex; int paginaScelta = (IndiceScelto <= 3) ? 1 : reader.NumberOfPages; iTextSharp.text.Rectangle rect = reader.GetPageSize(paginaScelta); int w = Convert.ToInt32(rect.Width); int h = Convert.ToInt32(rect.Height); Pagina = paginaScelta; /* istruzioni: * 0 Prima Pagina in Alto a Sinistra * 1 Prima Pagina in Alto a Destra * 2 Prima Pagina in Basso a Sinistra * 3 Prima Pagina in Basso a Destra * 4 Ultima Pagina in Alto a Sinistra * 5 Ultima Pagina in Alto a Destra * 6 Ultima Pagina in Basso a Sinistra * 7 Ultima Pagina in Basso a Destra */ switch (IndiceScelto) { case 0: default: case 4: posX = 20; posY = h - 110; Larghezza = posX + 100; Altezza = posY + 100; break; case 1: case 5: posX = w - 110; posY = h - 110; Larghezza = posX + 100; Altezza = posY + 100; break; case 2: case 6: posX = 20; posY = 20; Larghezza = posX + 350; Altezza = posY + 70; break; case 3: case 7: posX = w - 110; posY = 20; Larghezza = posX + 100; Altezza = posY + 100; break; } } sap.SetVisibleSignature(new iTextSharp.text.Rectangle(posX, posY, Larghezza, Altezza), Pagina, null); } sap.SignDate = DateTime.Now; sap.SetCrypto(null, chain, null, null); sap.Acro6Layers = true; sap.Render = PdfSignatureAppearance.SignatureRender.Description; //.NameAndDescription; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic.Date = new PdfDate(sap.SignDate); dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); sap.Layer2Text = "Firmato Digitalmente da: " + PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); sap.Layer2Text += "\r\nData: " + sap.SignDate; sap.Layer2Text += "\r\nRagione: " + sap.Reason; if (sap.Reason != null) { dic.Reason = sap.Reason; } if (sap.Location != null) { dic.Location = sap.Location; } if (sap.Contact != null) { dic.Contact = sap.Contact; } sap.CryptoDictionary = dic; int contentEstimated = 56000; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); Stream s = sap.GetRangeStream(); MemoryStream ss = new MemoryStream(); int read = 0; byte[] buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { ss.Write(buff, 0, read); } byte[] pk; if (tsaCbx.Checked) //ss.ToArray() { pk = SignMsg(ss.ToArray(), card, true, tsaCbx.Checked, TSAUrlTextBox.Text, tsaLogin.Text, tsaPwd.Text); } else { pk = SignMsg(ss.ToArray(), card, true, false, "", "", ""); } byte[] outc = new byte[contentEstimated]; PdfDictionary dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); sap.Close(dic2); //avanzo di 1 la progress bar pb.Increment(1); } MessageBox.Show(pb.Maximum.ToString() + " file firmati correttamente", "Operazione Completata"); pb.Visible = false; } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Messaggio dal Sistema Windows"); pb.Visible = false; } } }