static void PKCS7SignDocument( AsymmetricKeyParameter privateKey, X509Certificate[] certificateChain, PdfSignatureAppearance signatureAppearance, string algorithm) { DateTime timestamp = signatureAppearance.SignDate; PdfPKCS7 pdfPKCS7signature = new PdfPKCS7(privateKey, certificateChain, null, algorithm, false); // Get signature hash & certificate chain OCSP byte[] hash = CreateMessageDigestHash(signatureAppearance.RangeStream, "SHA-256"); byte[] ocsp = GetCertificateChainOCSP(certificateChain); byte[] authAttributeBytes = pdfPKCS7signature.GetAuthenticatedAttributeBytes(hash, timestamp, ocsp); pdfPKCS7signature.Update(authAttributeBytes, 0, authAttributeBytes.Length); byte[] encodedSignature = pdfPKCS7signature.GetEncodedPKCS7(hash, timestamp); byte[] paddedSignature = new byte[ContentEstimated]; System.Array.Copy(encodedSignature, 0, paddedSignature, 0, encodedSignature.Length); if (ContentEstimated + 2 < encodedSignature.Length) { throw new Exception("Not enough space for signature"); } PdfDictionary dict = new PdfDictionary(); dict.Put(PdfName.CONTENTS, new PdfString(paddedSignature).SetHexWriting(true)); signatureAppearance.Close(dict); }
public byte[] SignHash(string hexhash, string password) { byte[] hash = StringToByteArray(hexhash); Pkcs12Store store = new Pkcs12Store(getCertificate(), password.ToCharArray()); String alias = ""; foreach (string al in store.Aliases) { if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate) { alias = al; break; } } AsymmetricKeyEntry pk = store.GetKey(alias); X509CertificateEntry[] chain = store.GetCertificateChain(alias); List <Org.BouncyCastle.X509.X509Certificate> c = new List <Org.BouncyCastle.X509.X509Certificate>(); foreach (X509CertificateEntry en in chain) { c.Add(en.Certificate); } PrivateKeySignature signature = new PrivateKeySignature(pk.Key, "SHA256"); String hashAlgorithm = signature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, c, hashAlgorithm, false); DateTime signingTime = DateTime.Now; byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS); byte[] extSignature = signature.Sign(sh); sgn.SetExternalDigest(extSignature, null, signature.GetEncryptionAlgorithm()); return(sgn.GetEncodedPKCS7(hash, null, null, null, CryptoStandard.CMS)); }
/** * Sets the crypto information to sign. * @param privKey the private key * @param certChain the certificate chain * @param crlList the certificate revocation list. It can be <CODE>null</CODE> */ public void SetSignInfo(ICipherParameters privKey, X509Certificate[] certChain, object[] crlList) { pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, PdfName.ADBE_PKCS7_SHA1.Equals(Get(PdfName.SUBFILTER))); pkcs.SetExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); if (PdfName.ADBE_X509_RSA_SHA1.Equals(Get(PdfName.SUBFILTER))) { MemoryStream bout = new MemoryStream(); for (int k = 0; k < certChain.Length; ++k) { byte[] tmp = certChain[k].GetEncoded(); bout.Write(tmp, 0, tmp.Length); } bout.Close(); Cert = bout.ToArray(); Contents = pkcs.GetEncodedPKCS1(); } else { Contents = pkcs.GetEncodedPKCS7(); } name = PdfPKCS7.GetSubjectFields(pkcs.SigningCertificate).GetField("CN"); if (name != null) { Put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); } pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, PdfName.ADBE_PKCS7_SHA1.Equals(Get(PdfName.SUBFILTER))); pkcs.SetExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); }
public ActionResult Complete(SignatureCompleteModel model) { byte[] signedPdf; try { // Recover session data from Index action var sessionModel = Session["ITextSessionModel"] as ITextSessionModel; if (sessionModel == null) { // This should not happen return(RedirectToAction("Index")); } // Decode Certificate var certificate = new X509CertificateParser().ReadCertificate(model.CertContent); // Compute the external digest var pkcs7 = new PdfPKCS7(null, new X509Certificate[] { certificate }, DigestAlgorithm, false); pkcs7.SetExternalDigest(model.Signature, null, "RSA"); // Get a padded PKCS#7 byte[] pkcs7Encoded = pkcs7.GetEncodedPKCS7(sessionModel.RangeDigest); if (pkcs7Encoded.Length > 8192) // It shouldn't happen { throw new InvalidOperationException("PKCS37 encoded shouldn't be bigger than the space reserved for it"); } byte[] pkcs7Padded = new byte[8192]; pkcs7Encoded.CopyTo(pkcs7Padded, 0); // Instanciate a PDF dictionary var sigDictionary = new PdfDictionary(); // Write the PKCS#7 padded on the signature dictionary sigDictionary.Put(PdfName.CONTENTS, new PdfString(pkcs7Padded).SetHexWriting(true)); // Finally, close the PDF appearance to finish the signature process sessionModel.SignatureApperance.Close(sigDictionary); // Receive the signed PDF bytes from the its stream, which was storage by the session variable signedPdf = sessionModel.SignedPdfStream.ToArray(); // Close the signed PDF stream sessionModel.SignedPdfStream.Close(); } catch (Exception ex) { ModelState.AddModelError("", ex.ToString()); return(View()); } finally { // Clear the object stored on the Session Session.Remove("SignatureCompleteModel"); } TempData["SignatureInfoModel"] = new SignatureInfoModel() { File = Storage.StoreFile(signedPdf, ".pdf") }; return(RedirectToAction("SignatureInfo")); }
public byte[] Sign(Stream data) { PrivateKeySignature signature = new PrivateKeySignature(pk.Key, "SHA256"); String hashAlgorithm = signature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime signingTime = DateTime.Now; byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, signingTime, null, null, CryptoStandard.CMS); byte[] extSignature = signature.Sign(sh); sgn.SetExternalDigest(extSignature, null, signature.GetEncryptionAlgorithm()); return(sgn.GetEncodedPKCS7(hash, signingTime, null, null, null, CryptoStandard.CMS)); }
public byte[] Sign(Stream inputStream) { try { String hashAlgorithm = DigestAlgorithms.SHA256; PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); sgn.SetExternalDigest(signedHash, null, "RSA"); return(sgn.GetEncodedPKCS7(hash, PdfSigner.CryptoStandard.CMS, null, null, null)); } catch (IOException ioe) { throw new Exception(ioe.Message); } }
public void verify(byte[] byte_pdfData, X509Certificate2 trustCert, string signatureName) { PdfReader pdfReader = new PdfReader(byte_pdfData); AcroFields acroField = pdfReader.AcroFields; if (signatureName == null || "".CompareTo(signatureName) != 0) { signatureName = acroField.GetSignatureNames().Last(); } PdfPKCS7 pdfP7 = acroField.VerifySignature(signatureName); if (pdfP7 == null) { throw new NullReferenceException("Invalid signatureName:" + signatureName); } if (!pdfP7.Verify()) { throw new PdfException("Unable to verify specified signature field, specify signature invalid"); } byte[] pkcs7Signatue = pdfP7.GetEncodedPKCS7(); CmsSignedData signedData = new CmsSignedData(pkcs7Signatue); // Get signer certificate from CMSSignedData IX509Store x509Certs = signedData.GetCertificates("Collection"); ICollection cerlist = x509Certs.GetMatches(null); IEnumerator cEnum = cerlist.GetEnumerator(); ArrayList _chain = new ArrayList(); while (cEnum.MoveNext()) { Org.BouncyCastle.X509.X509Certificate cer = (Org.BouncyCastle.X509.X509Certificate)cEnum.Current; X509Certificate2 cer2 = new X509Certificate2(cer.GetEncoded()); _chain.Add(cer2); } X509Certificate2[] certChain = (X509Certificate2[])_chain.ToArray(typeof(X509Certificate2)); validateSignature(signedData, certChain[0]); }
internal static byte[] SignDocBytesHash(byte[] docBytesHash, ICipherParameters pk, X509Certificate[] chain ) { if (pk == null || chain == null) { return(null); } byte[] signatureContent = null; try { PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, HASH_ALGORITHM, false); byte[] attributes = pkcs7.GetAuthenticatedAttributeBytes(docBytesHash, null, null, PdfSigner.CryptoStandard .CMS); PrivateKeySignature signature = new PrivateKeySignature(pk, HASH_ALGORITHM); byte[] attrSign = signature.Sign(attributes); pkcs7.SetExternalDigest(attrSign, null, signature.GetEncryptionAlgorithm()); signatureContent = pkcs7.GetEncodedPKCS7(docBytesHash, null, null, null, PdfSigner.CryptoStandard.CMS); } catch (GeneralSecurityException) { } // dummy catch clause return(signatureContent); }
public byte[] Sign(Stream inputStream) { try { PrivateKeySignature signature = new PrivateKeySignature(pk, "SHA256"); String hashAlgorithm = signature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); byte[] hash = DigestAlgorithms.Digest(inputStream, hashAlgorithm); byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, PdfSigner.CryptoStandard.CMS, null, null); byte[] extSignature = signature.Sign(sh); sgn.SetExternalDigest(extSignature, null, signature.GetEncryptionAlgorithm()); return(sgn.GetEncodedPKCS7(hash, PdfSigner.CryptoStandard.CMS, null, null, null)); } catch (IOException ioe) { throw new Exception(ioe.Message); } }
public byte[] Sign(Stream data) { BasicOcspResp basicResp = (BasicOcspResp)ocspResp.GetResponseObject(); byte[] oc = basicResp.GetEncoded(); Collection <byte[]> ocspCollection = new Collection <byte[]>(); ocspCollection.Add(oc); String hashAlgorithm = "SHA256"; PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); byte[] hash = DigestAlgorithms.Digest(data, DigestAlgorithms.GetMessageDigest(hashAlgorithm)); byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, PdfSigner.CryptoStandard.CADES, ocspCollection, null); //create sha256 message digest using (SHA256 sha256 = SHA256.Create()) { sh = sha256.ComputeHash(sh); } //create hex encoded sha256 message digest String hexencodedDigest = new BigInteger(1, sh).ToString(16).ToUpper(); JObject signed = PDFSigningService.Sign(baseURL, id, hexencodedDigest, access); String sig = (String)signed.GetValue("signature"); //decode hex signature byte[] dsg = Hex.Decode(sig); //include signature on PDF sgn.SetExternalDigest(dsg, null, "RSA"); //create TimeStamp Client ITSAClient tsc = new DSSTSAClient(access); return(sgn.GetEncodedPKCS7(hash, PdfSigner.CryptoStandard.CADES, tsc, ocspCollection, null)); }
private void Sign(string hash) { try { byte[] result = System.Convert.FromBase64String(hash); sgn.SetExternalDigest(result, null, "RSA"); byte[] encodesig = sgn.GetEncodedPKCS7(hashValue, null /* tsa client */, null, null, CryptoStandard.CADES); sap.Close(this.AttachSignedContent(encodesig)); } catch (Exception ex) { if (document != null) { document.Close(); } if (pdfStamper != null) { pdfStamper.Close(); } throw ex; } }
/// <summary> /// Append signature and optional data to the temporary PDF document /// </summary> /// <param name="data"></param> /// <returns></returns> public byte[] Sign(Stream data) { /*var sgn = new PdfPKCS7(null, _certificates.ToArray(),DigestAlgorithms.SHA256, false); * sgn.SetExternalDigest(_signature, null, "RSA"); * return sgn.GetEncodedPKCS7();*/ var sgn = new PdfPKCS7(null, _certificates.ToArray(), DigestAlgorithms.SHA256, false); // set the signature bytes sgn.SetExternalDigest(_signature, null, "RSA"); // call GetEncoded with the same parameters as the original GetAuthenticatedAtt... var encodedSig = sgn.GetEncodedPKCS7(_documentHash, PdfSigner.CryptoStandard.CMS, _tsaClient, _ocspBytes?.ToList(), _crlBytesCollection?.ToList()); return(encodedSig); }
private void SignUsingEstEIDCard2(string filename, string outfile) { statusHandler(Resources.VERIFYING_DOCUMENT, false); AcroFields af = this.reader.AcroFields; ArrayList names = af.GetSignatureNames(); bool nextRevision = ((names != null) && (names.Count > 0)); // already signed ? if (nextRevision) { // pick always first signature string name = (string)names[0]; PdfPKCS7 pkc7 = af.VerifySignature(name); bool verify = pkc7.Verify(); if (!verify) { string who = PdfPKCS7.GetSubjectFields(pkc7.SigningCertificate).GetField("CN"); throw new DocVerifyException(Resources.DOC_VERIFY_FAILED + who); } } statusHandler(Resources.CONNECTING_SMARTCARD, false); // open EstEID EstEIDReader estEidReader = new EstEIDReader(); string pkcs11_lib = conf.PKCS11DriverPath; bool b = estEidReader.Open(pkcs11_lib); if (b == false) { throw new Exception(Resources.PKCS11_OPEN); } statusHandler(Resources.READ_CERTS, false); PKCS11Signer signer = LocateSigner(estEidReader); Org.BouncyCastle.X509.X509Certificate[] chain = X509Utils.LoadCertificate(signer.Cert.RawData); statusHandler(Resources.VERIFYING_OCSP, false); OCSPClientEstEID ocspClient = OCSPClient(chain[0]); if (ocspClient == null) { throw new Exception(this.lastError); } byte[] ocsp = ocspClient.GetEncoded(); if (ocsp == null) { throw new RevocationException(ocspClient.lastError); } X509Certificate2 card = signer.Cert; Oid oid = card.SignatureAlgorithm; if (oid.Value != PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id) { throw new Exception(Resources.INVALID_CERT); } PdfReader reader = new PdfReader(filename); Document document = new Document(reader.GetPageSizeWithRotation(1)); PdfStamper stp = PdfStamper.CreateSignature(reader, new FileStream(outfile, FileMode.Create), '\0', null, nextRevision); if (metadata != null) { stp.XmpMetadata = metadata.getStreamedMetaData(); } PdfSignatureAppearance sap = stp.SignatureAppearance; if (appearance.Visible) { if (appearance.SigLocation.UseSector) { appearance.SigLocation.Bounds = document.PageSize; } sap.SetVisibleSignature(appearance.SigLocation, (int)appearance.Page, null); } sap.SignDate = DateTime.Now; sap.SetCrypto(null, chain, null, null); sap.Reason = (appearance.Reason.Length > 0) ? appearance.Reason : null; sap.Location = (appearance.Location.Length > 0) ? appearance.Location : null; sap.Contact = (appearance.Contact.Length > 0) ? appearance.Contact : null; sap.Acro6Layers = true; sap.Render = appearance.SignatureRender; sap.Layer2Text = appearance.SignatureText(sap.SignDate, chain[0]); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_SHA1); 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; sap.SetExternalDigest(new byte[SIGNATURE_LENGTH], new byte[Digest.SHA1_LENGTH], "RSA"); // expect 6K to be enough if TSA response, else 2K ? int csize = (stamp != null) ? 1024 * 6 : 1024 * 2; Hashtable exc = new Hashtable(); exc[PdfName.CONTENTS] = csize * 2 + 2; sap.PreClose(exc); // compute hash based on PDF bytes byte[] digest = ComputeHash(estEidReader, sap); statusHandler(Resources.ADD_SIGNATURE, false); // sign hash byte[] rsadata = EstEIDCardSign(estEidReader, signer, digest); // if null, user requested Cancel if (rsadata == null) { throw new Exception(Resources.CARD_INTERNAL_ERROR); } // create PKCS#7 envelope PdfPKCS7 pk7 = new PdfPKCS7(null, chain, null, "SHA1", true); pk7.SetExternalDigest(rsadata, digest, "RSA"); byte[] pk = pk7.GetEncodedPKCS7(); // user wants to add TSA response ? if (stamp != null && pk != null) { statusHandler(Resources.TSA_REQUEST, false); pk = TimestampAuthorityResponse(estEidReader, pk); } // PKCS#7 bytes too large ? if (pk.Length >= csize) { throw new Exception(Resources.MEMORY_ERROR); } 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); }
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); }
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(); }
/// <summary>Signs the document using the detached mode, CMS or CAdES equivalent.</summary> /// <remarks> /// Signs the document using the detached mode, CMS or CAdES equivalent. /// <br /><br /> /// NOTE: This method closes the underlying pdf document. This means, that current instance /// of PdfSigner cannot be used after this method call. /// </remarks> /// <param name="externalSignature">the interface providing the actual signing</param> /// <param name="chain">the certificate chain</param> /// <param name="crlList">the CRL list</param> /// <param name="ocspClient">the OCSP client</param> /// <param name="tsaClient">the Timestamp client</param> /// <param name="externalDigest">an implementation that provides the digest</param> /// <param name="estimatedSize">the reserved size for the signature. It will be estimated if 0</param> /// <param name="sigtype">Either Signature.CMS or Signature.CADES</param> /// <exception cref="System.IO.IOException"/> /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/> public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain, ICollection <ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, PdfSigner.CryptoStandard sigtype) { if (closed) { throw new PdfException(PdfException.ThisInstanceOfPdfSignerAlreadyClosed); } ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < chain.Length) { crlBytes = ProcessCrl(chain[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; } } PdfSignatureAppearance appearance = GetSignatureAppearance(); appearance.SetCertificate(chain[0]); if (sigtype == PdfSigner.CryptoStandard.CADES) { AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL2); } PdfSignature dic = new PdfSignature(PdfName.Adobe_PPKLite, sigtype == PdfSigner.CryptoStandard.CADES ? PdfName .ETSI_CAdES_DETACHED : PdfName.Adbe_pkcs7_detached); dic.SetReason(appearance.GetReason()); dic.SetLocation(appearance.GetLocation()); dic.SetSignatureCreator(appearance.GetSignatureCreator()); dic.SetContact(appearance.GetContact()); dic.SetDate(new PdfDate(GetSignDate())); // time-stamp will over-rule this cryptoDictionary = dic; IDictionary <PdfName, int?> exc = new Dictionary <PdfName, int?>(); exc[PdfName.Contents] = estimatedSize * 2 + 2; PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7((ICipherParameters)null, chain, hashAlgorithm, false); Stream data = GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, SignUtils.GetMessageDigest(hashAlgorithm)); byte[] ocsp = null; if (chain.Length >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded((X509Certificate)chain[0], (X509Certificate)chain[1], null); } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize < encodedSig.Length) { throw new System.IO.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)); Close(dic2); closed = true; }
private static void DoSignPdfFile(PdfStamper stamper, ConversionProfile profile, JobPasswords jobPasswords) { var 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; var x = ks.GetCertificateChain(alias); var chain = new X509Certificate[x.Length]; for (var 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); } } var 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 clawPDF) psa.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS; } psa.Reason = signing.SignReason; psa.Contact = signing.SignContact; psa.Location = signing.SignLocation; if (signing.DisplaySignatureInDocument) { var 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); var messageDigest = DigestUtilities.GetDigest(hashAlgorithm); var 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) { var url = PdfPKCS7.GetOCSPURL(chain[0]); if (!string.IsNullOrEmpty(url)) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); } } var cal = psa.SignDate; var 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 { var 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); }
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(); }
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()); }