/** * 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.RangeStream; 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 AddSignature(string PathSource, string PathTarget, string CertPath, string CertPass, int lx = 100, int ly = 100, int ux = 250, int uy = 150, int page = 1, bool Visible = true) { try { Org.BouncyCastle.Crypto.AsymmetricKeyParameter Akp = null; Org.BouncyCastle.X509.X509Certificate[] Chain = null; string alias = null; Org.BouncyCastle.Pkcs.Pkcs12Store pk12; pk12 = new Org.BouncyCastle.Pkcs.Pkcs12Store(new System.IO.FileStream(CertPath, System.IO.FileMode.Open, System.IO.FileAccess.Read), CertPass.ToCharArray()); IEnumerable aliases = pk12.Aliases; foreach (string aliasTemp in aliases) { alias = aliasTemp; if (pk12.IsKeyEntry(alias)) { break; } } Akp = pk12.GetKey(alias).Key; Org.BouncyCastle.Pkcs.X509CertificateEntry[] ce = pk12.GetCertificateChain(alias); Chain = new Org.BouncyCastle.X509.X509Certificate[ce.Length]; for (int k = 0; k < ce.Length; ++k) { Chain[k] = ce[k].Certificate; } iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(PathSource); iTextSharp.text.pdf.PdfStamper st = iTextSharp.text.pdf.PdfStamper.CreateSignature(reader, new System.IO.FileStream(PathTarget, System.IO.FileMode.Create, System.IO.FileAccess.Write), '\0', null, true); iTextSharp.text.pdf.PdfSignatureAppearance sap = st.SignatureAppearance; if (Visible == true) { page = (page <1 || page> reader.NumberOfPages) ? 1 : page; sap.SetVisibleSignature(new iTextSharp.text.Rectangle(lx, ly, ux, uy), page, null); } sap.CertificationLevel = iTextSharp.text.pdf.PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; // digital signature - http://itextpdf.com/examples/iia.php?id=222 IExternalSignature es = new PrivateKeySignature(Akp, "SHA-256"); // "BC" MakeSignature.SignDetached(sap, es, new X509Certificate[] { pk12.GetCertificate(alias).Certificate }, null, null, null, 0, CryptoStandard.CMS); st.Close(); return(""); } catch (Exception e) { return(e.Message); } }
public static void SetAppearance(YapsConfig config, PdfSignatureAppearance sap) { var appearance = config.Appearance ?? new SignatureAppearance(); sap.Reason = appearance.Reason; sap.Contact = appearance.Contact; sap.Location = appearance.Location; sap.SignDate = DateTime.Now; sap.Acro6Layers = true; if (!config.Visible || !appearance.ValidateRect()) return; //iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page); var xi = appearance.X + appearance.Width; var yi = appearance.Y + appearance.Height; var rect = new iTextSharp.text.Rectangle(appearance.X, appearance.Y, xi, yi); //sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData); if (!string.IsNullOrEmpty(appearance.CustomText)) sap.Layer2Text = appearance.CustomText; //sap.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 100, 300, 200), 1, "Signature"); sap.SetVisibleSignature(rect, appearance.Page, "Signature"); }
private static void SetSigText(PdfSignatureAppearance sigAppearance, IList<X509Certificate> chain) { sigAppearance.SignDate = DateTime.Now; var signedBy = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"); var signedOn = sigAppearance.SignDate; sigAppearance.Layer2Text = String.Format(SigTextFormat, signedBy, signedOn); }
private static void SetSigPosition(PdfSignatureAppearance sigAppearance, int oldSigCount) { //Note: original formula from QuangNgV, ll = lower left, ur = upper right, coordinates are calculated relative from the lower left of the pdf page float llx = (100 + 20) * (oldSigCount % 5), lly = (25 + 20) * (oldSigCount / 5), urx = llx + 100, ury = lly + 25; sigAppearance.SetVisibleSignature(new Rectangle(llx, lly, urx, ury), 1, null); }
private static void SetSigCryptoFromX509(PdfSignatureAppearance sigAppearance, X509Certificate2 card, X509Certificate[] chain) { sigAppearance.SetCrypto(null, chain, null, PdfSignatureAppearance.WINCER_SIGNED); var dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1) { Date = new PdfDate(sigAppearance.SignDate), Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN"), Reason = sigAppearance.Reason, Location = sigAppearance.Location }; sigAppearance.CryptoDictionary = dic; const int csize = 4000; var exc = new Dictionary<PdfName, int> { { PdfName.CONTENTS, csize * 2 + 2 } }; sigAppearance.PreClose(exc); HashAlgorithm sha = new SHA1CryptoServiceProvider(); var s = sigAppearance.RangeStream; int read; var buff = new byte[8192]; while ((read = s.Read(buff, 0, 8192)) > 0) { sha.TransformBlock(buff, 0, read, buff, 0); } sha.TransformFinalBlock(buff, 0, 0); var pk = SignMsg(sha.Hash, card, false); var outc = new byte[csize]; var dic2 = new PdfDictionary(); Array.Copy(pk, 0, outc, 0, pk.Length); dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); sigAppearance.Close(dic2); }
private static void SetSigCryptoFromCipherParam(PdfSignatureAppearance sigAppearance, ICipherParameters key, X509Certificate[] chain) { sigAppearance.SetCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); }
/// <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"; } DataSize = sapStream.Length; } // sanity check if (DataReadCount > 2) throw new InvalidOperationException("DataReadCount"); } while (isOdd); } catch { throw; } finally { HttpContext.Current.Session[InstanceLookupKey] = this; if (reader != null) { reader.Dispose(); } } return Convert.ToBase64String(pdfRawContent); }
private void signDetached(PdfSignatureAppearance signAppearance) { signAppearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; var es = new PrivateKeySignature(_asymmetricKeyParameter, "SHA-256"); MakeSignature.SignDetached(signAppearance, es, _chain, null, null, null, 0, CryptoStandard.CMS); }
private void addVisibleSignature(PdfSignatureAppearance signAppearance, PdfStamper stamper) { if (SignatureData.VisibleSignature == null) return; signAppearance.Image = string.IsNullOrEmpty(SignatureData.VisibleSignature.ImagePath) ? null : Image.GetInstance(SignatureData.VisibleSignature.ImagePath); signAppearance.Layer2Text = SignatureData.VisibleSignature.CustomText; if (SignatureData.VisibleSignature.RunDirection == null) SignatureData.VisibleSignature.RunDirection = PdfRunDirection.LeftToRight; signAppearance.RunDirection = (int)SignatureData.VisibleSignature.RunDirection; signAppearance.Layer2Font = SignatureData.VisibleSignature.Font.Fonts[0]; var pageNumber = SignatureData.VisibleSignature.UseLastPageToShowSignature ? stamper.Reader.NumberOfPages : SignatureData.VisibleSignature.PageNumberToShowSignature; signAppearance.SetVisibleSignature(SignatureData.VisibleSignature.Position, pageNumber, null); }
private void addTsa(PdfSignatureAppearance signAppearance) { var es = new PrivateKeySignature(_asymmetricKeyParameter, "SHA-256"); var tsc = new TSAClientBouncyCastle(SignatureData.TsaClient.Url, SignatureData.TsaClient.UserName, SignatureData.TsaClient.Password); MakeSignature.SignDetached(signAppearance, es, _chain, null, null, tsc, 0, CryptoStandard.CMS); }
private void UpdatePdfDictionaryContents(PdfSignatureAppearance pdfSignatureAppearance, byte[] encodedSignature) { var pdfDictionary = new PdfDictionary(); var paddedSignature = new byte[SIGNATURE_ESTIMATED_SIZE]; Array.Copy(encodedSignature, 0, paddedSignature, 0, encodedSignature.Length); pdfDictionary.Put(PdfName.CONTENTS, new PdfString(paddedSignature).SetHexWriting(true)); pdfSignatureAppearance.Close(pdfDictionary); }
private static void CreateSignature(SigningCertificates signingCertificates, PdfSignatureAppearance signatureAppearance, ICollection<ICrlClient> clrClients, IOcspClient oscpClient) { IExternalSignature externalSignature = new X509Certificate2Signature(signingCertificates.X509Certificate2, "SHA-1"); MakeSignature.SignDetached(signatureAppearance, externalSignature, signingCertificates.FinalChain, clrClients, oscpClient, null, 0, CryptoStandard.CMS); }
/// <summary> /// Assina o arquivo PDF /// </summary> /// <param name="filePath">Caminho do arquivo</param> /// <param name="certificate">Certificado</param> /// <param name="reason">Motivo da assinatura</param> internal static void sign(string filePath, X509Certificate2 certificate, string reason = null) { try { // make the certificate chain IList <BCX.X509Certificate> chain = getCertChain(certificate); // open the original file TS.PdfReader reader = new TS.PdfReader(filePath); string newFilePath = filePath.Substring(0, filePath.Length - 4) + "_signed.pdf"; // create a new file FileStream fout = new FileStream(newFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); // create the "stamp" on the file TS.PdfStamper stamper = TS.PdfStamper.CreateSignature(reader, fout, '\0', null, true); TS.PdfSignatureAppearance appearance = stamper.SignatureAppearance; appearance.Reason = reason; appearance.Location = getLocation(certificate.Subject); int i = 1; int xdiff = 0; while (true) { string fieldName = "Assinatura" + i.ToString();; try { appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20 + xdiff, 10, 170 + xdiff, 60), 1, fieldName); TSS.X509Certificate2Signature es = new TSS.X509Certificate2Signature(certificate, "SHA-1"); TSS.MakeSignature.SignDetached(appearance, es, chain, null, null, null, 0, TSS.CryptoStandard.CMS); break; } catch (Exception ex) { if (ex.Message != "The field " + fieldName + " already exists.") { throw ex; } else { i++; xdiff += 180; } } } // close the files reader.Close(); fout.Close(); // delete the tmp file e move the new to the right name System.IO.File.Delete(filePath); System.IO.File.Move(newFilePath, filePath); } catch (Exception ex) { throw ex; } }