protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set the security context to be used to determine trust in the certificate chain SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature (see function below) VisualRepresentation = getVisualRepresentation(), }; /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occur with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // If the user was redirected here by Upload (signature with file uploaded by user), the "userfile" URL argument // will contain the filename under the "App_Data" folder. Otherwise (signature with server file), we'll sign a sample // document. UserFile = Request.QueryString["userfile"]; if (string.IsNullOrEmpty(UserFile)) { // Set the PDF to be signed as a byte array signatureStarter.SetPdfToSign(Util.GetSampleDocContent()); } else { // Set the path of the file to be signed signatureStarter.SetPdfToSign(Server.MapPath("~/App_Data/" + UserFile)); } // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); ViewState["Token"] = token; } }
public ActionResult Start(int id) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = getVisualPositioning(1) } }; // Set the document to be signed based on its ID (passed to us from the page) signatureStarter.SetPdfToSign(Util.GetBatchDocContent(id)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); // Notice: it is not necessary to call SetNoCacheHeaders() because this action is a POST action, therefore no caching // of the response will be made by browsers. // Return a JSON with the token obtained from REST PKI (the page will use jQuery to decode this value) return(Json(token)); }
public async Task <ActionResult> Start(int id) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature // elements and start the signature process. var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations. MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy. SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set the security context to be used to determine trust in the certificate chain. We have // encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature. VisualRepresentation = PadesVisualElements.GetVisualRepresentationForRestPki() }; // Set the document to be signed based on its ID (passed to us from the page). signatureStarter.SetPdfToSign(StorageMock.GetBatchDocPath(id)); /* * Optionally, add marks to the PDF before signing. These differ from the signature visual * representation in that they are actually changes done to the document prior to signing, not * binded to any signature. Therefore, any number of marks can be added, for instance one per * page, whereas there can only be one visual representation per signature. However, since the * marks are in reality changes to the PDF, they can only be added to documents which have no * previous signatures, otherwise such signatures would be made invalid by the changes to the * document (see property PadesSignatureStarter.BypassMarksIfSigned). This problem does not * occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the * argument passed. Experiment changing the argument to see different examples of PDF marks. * Once you decide which is best for your case, you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, // a 43-character case-sensitive URL-safe string, which identifies this signature process. We'll // use this value to call the signWithRestPki() method on the Web PKI component (see // batch-signature-form.js) and also to complete the signature on the POST action below (this // should not be mistaken with the API access token). var token = await signatureStarter.StartWithWebPkiAsync(); // Return a JSON with the token obtained from REST PKI. (the page will use jQuery to decode this // value) return(Json(token)); }
public static string Start(int id) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set the security context to be used to determine trust in the certificate chain SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature (see function below) VisualRepresentation = getVisualRepresentation(), }; /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Set the PDF to be signed signatureStarter.SetPdfToSign(Util.GetBatchDocContent(id)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see batch-signature-optimized-form.js) and also to complete // the signature on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); // Send to the javascript the token of the signature process to be used to call Web PKI to perform the signature return(token); }
public ActionResult Start(BatchSignatureStartRequest request) { // Recover the batch information based on its ID, which contains the user's certificate var batchInfo = batches[request.BatchId]; // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the user's certificate. Notice that this step is not necessary on the regular batch signature example. This // enhances the performance of the batch processing SignerCertificate = Convert.FromBase64String(batchInfo.Certificate), // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = getVisualPositioning(1) } }; // Set the document to be signed based on its ID (passed to us from the page) signatureStarter.SetPdfToSign(Util.GetBatchDocContent(request.DocumentId)); // Call the Start() method, which initiates the signature. Notice that, on the regular signature example, we call the // StartWithRestPki() method, which is simpler but with worse performance. The Start() method will yield not only the // token, a 43-character case-sensitive URL-safe string which identifies this signature process, but also the data // that should be used to call the signHash() function on the Web PKI component (instead of the signWithRestPki() // function, which is also simpler but far slower). var signatureParams = signatureStarter.Start(); // Notice: it is not necessary to call SetNoCacheHeaders() because this action is a POST action, therefore no caching // of the response will be made by browsers. // Return a JSON with the token obtained from REST PKI, along with the parameters for the signHash() call // (the page will use jQuery to decode this value) var response = new BatchSignatureStartResponse() { Token = signatureParams.Token, ToSignHash = Convert.ToBase64String(signatureParams.ToSignHash), DigestAlgorithmOid = signatureParams.DigestAlgorithmOid }; return(Json(response)); }
private async void signButtonClick(object sender, RoutedEventArgs e) { //var progressDialog = await this.ShowProgressAsync("Please wait...", "Signing"); Pkcs11CertificateStore p11Store = null; addLog($"Signature process begin"); progressBar.Value = 10; try { var signatureStarter = new PadesSignatureStarter(restPkiClient) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = Guid.Parse("803517ad-3bbc-4169-b085-60053a8f6dbf"), //SecurityContextId =StandardSecurityContexts.PkiBrazil, // Note: this SecurityContext above accept unsecured certificates. You can create custom security context on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = createVisualRepresentation() }; progressBar.Value = 15; // If the user was redirected here by UploadController (signature with file uploaded by user), the "userfile" URL argument // will contain the filename under the "App_Data" folder. Otherwise (signature with server file), we'll sign a sample // document. if (string.IsNullOrEmpty(FileToSign)) { // Set the PDF to be signed as a byte array signatureStarter.SetPdfToSign(Signer.Resources.SampleDocument); } else { // Set the path of the file to be signed addLog($"file size {(new FileInfo(FileToSign).Length / 1024.0).ToString("0.00")} KBytes"); signatureStarter.SetPdfToSign(FileToSign); } /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). // Find selected certificate with key // -------------------------------------------------------------- PKCertificateWithKey certWithKey = null; var selectedThumbprint = (CertificatesCB.SelectedItem as ComboCertificate).Certificate.ThumbprintSHA256; p11Store = Pkcs11CertificateStore.Load(getPkcs11Modules(), new P11LoginProvider()); // search on pkcs11 store if (findCertificate(p11Store.GetCertificatesWithKey(), selectedThumbprint, out certWithKey)) { } else if (findCertificate(WindowsCertificateStore.LoadPersonalCurrentUser().GetCertificatesWithKey(), selectedThumbprint, out certWithKey)) { } else { throw new Exception("Selected certificate not found"); } // -------------------------------------------------------------- signatureStarter.SetSignerCertificate(certWithKey.Certificate.EncodedValue); progressBar.Value = 30; addLog($"Step 1: Start Signature"); var sw = Stopwatch.StartNew(); Token = await signatureStarter.StartAsync(); sw.Stop(); addLog($"Step 1: Signature Started, elapsed {sw.Elapsed.TotalSeconds:N1}s"); progressBar.Value = 50; addLog($"Signing with {certWithKey.Certificate.SubjectDisplayName}"); var signature = certWithKey.SignData(Lacuna.Pki.DigestAlgorithm.GetInstanceByOid(Token.DigestAlgorithmOid), Token.ToSignData); addLog($"Signed"); progressBar.Value = 70; var signatureFinisher = new PadesSignatureFinisher2(restPkiClient) { Token = Token.Token, Signature = signature }; sw = Stopwatch.StartNew(); // Call the Finish() method, which finalizes the signature process and returns a SignatureResult object addLog($"Step 2: Finish Signature"); var signatureResult = await signatureFinisher.FinishAsync(); sw.Stop(); addLog($"Step 2: Signature Finished, elapsed {sw.Elapsed.TotalSeconds:N1}s"); SignedFile = System.IO.Path.Combine(Path.GetDirectoryName(FileToSign), Path.GetFileNameWithoutExtension(FileToSign) + "-signed" + Path.GetExtension(FileToSign)); signatureResult.WriteToFile(SignedFile); //BusyIndicator.IsBusy = false; progressBar.Value = 100; OpenFileSignedBt.IsEnabled = true; addLog($"File signed: {SignedFile}"); } catch (Exception ex) { addLog(ex.ToString()); } finally { if (p11Store != null) { p11Store.Dispose(); } } progressBar.Value = 0; }
public async Task <ActionResult> Index(string userfile) { // Verify if the userfile exists and get its absolute path. string userfilePath; if (!StorageMock.TryGetFile(userfile, out userfilePath)) { return(HttpNotFound()); } // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature // elements and start the signature process. var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations. MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy. SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set the security context to be used to determine trust in the certificate chain. We have // encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature. VisualRepresentation = PadesVisualElements.GetVisualRepresentationForRestPki() }; // Set the file to be signed. signatureStarter.SetPdfToSign(userfilePath); /* * Optionally, add marks to the PDF before signing. These differ from the signature visual * representation in that they are actually changes done to the document prior to signing, not * binded to any signature. Therefore, any number of marks can be added, for instance one per * page, whereas there can only be one visual representation per signature. However, since the * marks are in reality changes to the PDF, they can only be added to documents which have no * previous signatures, otherwise such signatures would be made invalid by the changes to the * document (see property PadesSignatureStarter.BypassMarksIfSigned). This problem does not * occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the * argument passed. Experiment changing the argument to see different examples of PDF marks. * Once you decide which is best for your case, you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a // 43-character case-sensitive URL-safe string, which identifies this signature process. We'll // use this value to call the signWithRestPki() method on the Web PKI component (see // signature-forms.js) and also to complete the signature on the POST action below (this should // not be mistaken with the API access token). var token = await signatureStarter.StartWithWebPkiAsync(); // The token acquired above can only be used for a single signature attempt. In order to retry // the signature it is necessary to get a new token. This can be a problem if the user uses the // back button of the browser, since the browser might show a cached page that we rendered // previously, with a now stale token. To prevent this from happening, we call the method // SetNoCacheHeaders() (in BaseController) which sets HTTP headers to prevent caching of the // page. base.SetNoCacheHeaders(); // Render the signature page with the token obtained from REST PKI. return(View(new SignatureModel() { Token = token, UserFile = userfile })); }
private void startNextSignature() { // Increment the index of the document currently being signed DocumentIndex += 1; // Check if we have reached the end of the batch, in which case we fill the hidden field "TokenField" with value "(end)", // which signals to the javascript on batch-signature-form.js that the process is completed and the page can be unblocked. if (DocumentIndex == DocumentIds.Count) { TokenField.Value = "(end)"; return; } // Get the ID of the document currently being signed var docId = DocumentIds[DocumentIndex]; string token; try { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set the security context to be used to determine trust in the certificate chain SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature (see function below) VisualRepresentation = getVisualRepresentation(), }; /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Set the PDF to be signed signatureStarter.SetPdfToSign(Util.GetBatchDocContent(docId)); // Call the StartWithWebPki() method, which initiates the signature. token = signatureStarter.StartWithWebPki(); } catch (ValidationException ex) { // One or more validations failed. We log the error, update the page with a summary of what happened to this document and start the next signature setValidationError(ex.ValidationResults); startNextSignature(); return; } catch (Exception ex) { // An error has occurred. We log the error, update the page with a summary of what happened to this document and start the next signature setError(ex.Message); startNextSignature(); return; } // Send to the javascript the token of the signature process to be used to call Web PKI to perform the signature TokenField.Value = token; }
public async Task <ActionResult> Index(SignatureStartModel model) { ClientSideSignatureInstructions signatureParams; try { // Get an instance of the PadesSignatureStarter class, responsible for receiving the // signature elements and start the signature process. var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations. MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy. SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain. SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature. VisualRepresentation = new PadesVisualRepresentation() { // The tags {{name}} and {{national_id}} will be substituted according to the user's // certificate: // // name : Full name of the signer; // national_id : If the certificate is ICP-Brasil, contains the signer's CPF. // // For a full list of the supported tags, see: // https://github.com/LacunaSoftware/RestPkiSamples/blob/master/PadesTags.md Text = new PadesVisualText("Signed by {{name}} ({{national_id}})") { // Specify that the signing time should also be rendered. IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if // not set the default is Left. HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png. Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100. (0 is completely transparent, 100 is // completely opaque) Opacity = 50, // Align the image to the right. HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method // to include several possibilities depending on the argument passed. Experiment // changing the argument to see different examples of signature positioning. Once you // decide which is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(1) } }; // Set certificate's content. (received from a hidden field on the form submission, its value // is filled on javascript, see signature-start-form.js) signatureStarter.SetSignerCertificate(model.CertContent); // Set PDF to be signed. signatureStarter.SetPdfToSign(Util.GetSampleDocPath()); /* * Optionally, add marks to the PDF before signing. These differ from the signature visual * representation in that they are actually changes done to the document prior to signing, * not binded to any signature. Therefore, any number of marks can be added, for instance * one per page, whereas there can only be one visual representation per signature. However, * since the marks are in reality changes to the PDF, they can only be added to documents * which have no previous signatures, otherwise such signatures would be made invalid by the * changes to the document (see property PadesSignatureStarter.BypassMarksIfSigned). This * problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on * the argument passed. Experiment changing the argument to see different examples of PDF * marks. Once you decide which is best for your case, you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartAsync() method, which initiates the signature. This yields the parameters // for the signature using the certificates. signatureParams = await signatureStarter.StartAsync(); } catch (ValidationException ex) { // Return to Index view rendering the error message. ModelState.AddModelError("", ex.Message); return(View()); } // On the next step (Complete action), we'll need once again some information: // - The token that identifies the signature process on REST PKI service. // - The thumbprint of the selected certificate. // - The "to-sign-hash" to be signed. (see signature-complete-form.js) // - The OID of the digest algorithm to be used during the signature operation. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureCompleteModel"] = new SignatureCompleteModel() { Token = signatureParams.Token, CertThumb = model.CertThumb, ToSignHash = signatureParams.ToSignHash, DigestAlgorithmOid = signatureParams.DigestAlgorithmOid }; return(RedirectToAction("Complete")); }
private void startNextSignature() { // Increment the index of the document currently being signed DocumentIndex += 1; // Check if we have reached the end of the batch, in which case we fill the hidden field "TokenField" with value "(end)", // which signals to the javascript on batch-signature-form.js that the process is completed and the page can be unblocked. if (DocumentIndex == DocumentIds.Count) { TokenField.Value = "(end)"; return; } // Get the ID of the document currently being signed var docId = DocumentIds[DocumentIndex]; string token; try { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.PkiBrazil.BasicWithPkiBrazilCerts, // Note: Depending on the signature policy chosen above, setting the security context below may be mandatory (this is not // the case for ICP-Brasil policies, which will automatically use the PkiBrazil security context if none is passed) // Optionally, set a SecurityContext to be used to determine trust in the certificate chain //SecurityContextId = new Guid("ID OF YOUR CUSTOM SECURITY CONTEXT"), // For instance, to use the test certificates on Lacuna Test PKI (for development purposes only!): //SecurityContextId = new Guid("803517ad-3bbc-4169-b085-60053a8f6dbf"), // Set a visual representation for the signature VisualRepresentation = getVisualRepresentation(), }; // Set the PDF to sign signatureStarter.SetPdfToSign(Util.GetBatchDocPath(docId)); // Call the StartWithWebPki() method, which initiates the signature. token = signatureStarter.StartWithWebPki(); } catch (ValidationException ex) { // One or more validations failed. We log the error, update the page with a summary of what happened to this document and start the next signature //logger.Error(ex, "Validation error starting the signature of a batch document"); setValidationError(ex.ValidationResults); startNextSignature(); return; } catch (Exception ex) { // An error has occurred. We log the error, update the page with a summary of what happened to this document and start the next signature //logger.Error(ex, "Error starting the signature of a batch document"); setError(ex.Message); startNextSignature(); return; } // Send to the javascript the token of the signature process to be used to call Web PKI to perform the signature TokenField.Value = token; }
public ActionResult Start(BatchSignatureStartRequest request) { // Recover the batch information based on its ID, which contains the user's certificate var batchInfo = batches[request.BatchId]; // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the user's certificate. Notice that this step is not necessary on the regular batch signature example. This // enhances the performance of the batch processing SignerCertificate = batchInfo.Certificate, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = getVisualPositioning(1) } }; // Set the document to be signed based on its ID (passed to us from the page) signatureStarter.SetPdfToSign(Util.GetBatchDocContent(request.DocumentId)); // Call the Start() method, which initiates the signature. Notice that, on the regular signature example, we call the // StartWithRestPki() method, which is simpler but with worse performance. The Start() method will yield not only the // token, a 43-character case-sensitive URL-safe string which identifies this signature process, but also the data // that should be used to call the signHash() function on the Web PKI component (instead of the signWithRestPki() // function, which is also simpler but far slower). var signatureParams = signatureStarter.Start(); // Notice: it is not necessary to call SetNoCacheHeaders() because this action is a POST action, therefore no caching // of the response will be made by browsers. // Return a JSON with the token obtained from REST PKI, along with the parameters for the signHash() call // (the page will use jQuery to decode this value) var response = new BatchSignatureStartResponse() { Token = signatureParams.Token, ToSignHash = signatureParams.ToSignHash, DigestAlgorithmOid = signatureParams.DigestAlgorithmOid }; return Json(response); }
private async void signButtonClick(object sender, RoutedEventArgs e) { var progressDialog = await this.ShowProgressAsync("Please wait...", "Signing"); addLog($"Signature started"); progressDialog.SetProgress(0.10); try { var signatureStarter = new PadesSignatureStarter(restPkiClient) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = Guid.Parse("803517ad-3bbc-4169-b085-60053a8f6dbf"), //SecurityContextId =StandardSecurityContexts.PkiBrazil, // Note: this SecurityContext above accept unsecured certificates. You can create custom security context on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{name}} and {{national_id}} will be substituted according to the user's certificate // // name : full name of the signer // national_id : if the certificate is ICP-Brasil, contains the signer's CPF // // For a full list of the supported tags, see: https://github.com/LacunaSoftware/RestPkiSamples/blob/master/PadesTags.md Text = new PadesVisualText("Signed by {{name}} ({{national_id}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Signer.Resources.PdfStamp_png, "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(restPkiClient, 1) }, }; var cert = CertificatesCB.SelectedItem as Cert; var certificate = getCertificate(cert.Thumbprint); signatureStarter.SetSignerCertificate(certificate.GetRawCertData()); progressDialog.SetProgress(0.15); // If the user was redirected here by UploadController (signature with file uploaded by user), the "userfile" URL argument // will contain the filename under the "App_Data" folder. Otherwise (signature with server file), we'll sign a sample // document. if (string.IsNullOrEmpty(FileToSign)) { // Set the PDF to be signed as a byte array signatureStarter.SetPdfToSign(Signer.Resources.SampleDocument); } else { // Set the path of the file to be signed addLog($"file size {new FileInfo(FileToSign).Length / 1024}kBytes"); signatureStarter.SetPdfToSign(FileToSign); } /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). progressDialog.SetProgress(0.20); addLog($"Step One Started"); var sw = new Stopwatch(); sw.Start(); Token = await signatureStarter.StartAsync(); sw.Stop(); addLog($"Step One finished,elapsed {sw.Elapsed.TotalSeconds:N1}s"); progressDialog.SetProgress(0.40); byte[] signature; using (RSA rsa = certificate.GetRSAPrivateKey()) { HashAlgorithmName hashAlgorithm; switch (Token.DigestAlgorithm.ApiModel) { case DigestAlgorithms.MD5: hashAlgorithm = HashAlgorithmName.MD5; break; case DigestAlgorithms.SHA1: hashAlgorithm = HashAlgorithmName.SHA1; break; case DigestAlgorithms.SHA256: hashAlgorithm = HashAlgorithmName.SHA256; break; case DigestAlgorithms.SHA384: hashAlgorithm = HashAlgorithmName.SHA384; break; case DigestAlgorithms.SHA512: hashAlgorithm = HashAlgorithmName.SHA512; break; default: throw new ArgumentOutOfRangeException(); } signature = rsa.SignData(Token.ToSignData, hashAlgorithm, RSASignaturePadding.Pkcs1); var signatureFinisher = new PadesSignatureFinisher2(restPkiClient) { Token = Token.Token, Signature = signature }; progressDialog.SetProgress(0.50); // Call the Finish() method, which finalizes the signature process and returns a SignatureResult object sw.Reset(); sw.Start(); var signatureResult = await signatureFinisher.FinishAsync(); sw.Stop(); addLog($"Step two finished,elapsed {sw.Elapsed.TotalSeconds:N1}s"); SignedFile = System.IO.Path.Combine(Path.GetDirectoryName(FileToSign), Path.GetFileNameWithoutExtension(FileToSign) + "Signed" + Path.GetExtension(FileToSign)); signatureResult.WriteToFile(SignedFile); //BusyIndicator.IsBusy = false; progressDialog.SetProgress(0.99); OpenFileSignedBt.IsEnabled = true; addLog($"Signarure finished"); } } catch (Exception ex) { addLog(ex.ToString()); } await progressDialog.CloseAsync(); }
public ActionResult Start(int id) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = getVisualPositioning(1) } }; // Set the document to be signed based on its ID (passed to us from the page) signatureStarter.SetPdfToSign(Util.GetBatchDocContent(id)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); // Notice: it is not necessary to call SetNoCacheHeaders() because this action is a POST action, therefore no caching // of the response will be made by browsers. // Return a JSON with the token obtained from REST PKI (the page will use jQuery to decode this value) return Json(token); }
public async Task <ActionResult> Start(int id) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature // elements and start the signature process. var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the signature policy. SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain. We have // encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId(), // Set a visual representation for the signature. VisualRepresentation = new PadesVisualRepresentation() { // The tags {{name}} and {{national_id}} will be substituted according to the user's // certificate: // // name : Full name of the signer; // national_id : If the certificate is ICP-Brasil, contains the signer's CPF. // // For a full list of the supported tags, see: // https://github.com/LacunaSoftware/RestPkiSamples/blob/master/PadesTags.md Text = new PadesVisualText("Signed by {{name}} ({{national_id}})") { // Specify that the signing time should also be rendered. IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not // set the default is Left. HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png. Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is // completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to // include several possibilities depending on the argument passed. Experiment changing // the argument to see different examples of signature positioning. Once you decide which // is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(1) } }; // Set the document to be signed based on its ID. (passed to us from the page) signatureStarter.SetPdfToSign(Util.GetBatchDocPath(id)); /* * Optionally, add marks to the PDF before signing. These differ from the signature visual * representation in that they are actually changes done to the document prior to signing, not * binded to any signature. Therefore, any number of marks can be added, for instance one per * page, whereas there can only be one visual representation per signature. However, since the * marks are in reality changes to the PDF, they can only be added to documents which have no * previous signatures, otherwise such signatures would be made invalid by the changes to the * document (see property PadesSignatureStarter.BypassMarksIfSigned). This problem does not * occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the * argument passed. Experiment changing the argument to see different examples of PDF marks. * Once you decide which is best for your case, you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPkiAsync() method, which initiates the signature. This yields the token, // a 43-character case-sensitive URL-safe string, which identifies this signature process. We'll // use this value to call the signWithRestPki() method on the Web PKI component (see javascript // on the view) and also to complete the signature on the POST action below (this should not be // mistaken with the API access token). var token = await signatureStarter.StartWithWebPkiAsync(); // Notice: it is not necessary to call SetNoCacheHeaders() because this action is a POST action, // therefore no caching of the response will be made by browsers. // Return a JSON with the token obtained from REST PKI. (the page will use jQuery to decode this // value) return(Json(token)); }
public ActionResult Index(string userfile) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(1) }, }; // If the user was redirected here by UploadController (signature with file uploaded by user), the "userfile" URL argument // will contain the filename under the "App_Data" folder. Otherwise (signature with server file), we'll sign a sample // document. if (string.IsNullOrEmpty(userfile)) { // Set the PDF to be signed as a byte array signatureStarter.SetPdfToSign(Util.GetSampleDocContent()); } else { // Set the path of the file to be signed signatureStarter.SetPdfToSign(Server.MapPath("~/App_Data/" + userfile.Replace("_", "."))); // Note: we're passing the filename argument with "." as "_" because of limitations of ASP.NET MVC } /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); // The token acquired above can only be used for a single signature attempt. In order to retry the signature it is // necessary to get a new token. This can be a problem if the user uses the back button of the browser, since the // browser might show a cached page that we rendered previously, with a now stale token. To prevent this from happening, // we call the method SetNoCacheHeaders() (in BaseController) which sets HTTP headers to prevent caching of the page. base.SetNoCacheHeaders(); // Render the signature page with the token obtained from REST PKI return(View(new Models.PadesSignatureModel() { Token = token, UserFile = userfile })); }
public async Task <string> Start(string userfile) { var storage = new Storage(hostingEnvironment); var client = Util.GetRestPkiClient(restPkiConfig); // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(client) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.PkiBrazil.BasicWithPkiBrazilCerts, // Note: Depending on the signature policy chosen above, setting the security context below may be mandatory (this is not // the case for ICP-Brasil policies, which will automatically use the PkiBrazil security context if none is passed) // Optionally, set a SecurityContext to be used to determine trust in the certificate chain //SecurityContextId = new Guid("ID OF YOUR CUSTOM SECURITY CONTEXT"), // For instance, to use the test certificates on Lacuna Test PKI (for development purposes only!): //SecurityContextId = new Guid("803517ad-3bbc-4169-b085-60053a8f6dbf"), // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{name}} and {{br_cpf_formatted}} will be substituted according to the user's certificate // // name : full name of the signer // br_cpf_formatted : if the certificate is ICP-Brasil, contains the signer's CPF // // For a full list of the supported tags, see: https://github.com/LacunaSoftware/RestPkiSamples/blob/master/PadesTags.md Text = new PadesVisualText("Signed by {{name}} ({{br_cpf_formatted}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(storage.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(client, 1) } }; // Below we'll either set the PDF file to be signed. Prefer passing a path or a stream instead of the file's contents // as a byte array to prevent memory allocation issues with large files. // If the "userfile" URL argument is set, it will contain the filename under the "App_Data" folder. Otherwise // (signature with server file), we'll sign a sample document. if (string.IsNullOrEmpty(userfile)) { signatureStarter.SetPdfToSign(storage.GetSampleDocPath()); } else { Stream userFileStream; if (!storage.TryOpenRead(userfile, out userFileStream)) { throw new Exception("File not found"); } signatureStarter.SetPdfToSign(userFileStream); } /* * Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that * they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number * of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. * However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous * signatures, otherwise such signatures would be made invalid by the changes to the document (see property * PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. * * We have encapsulated this code in a method to include several possibilities depending on the argument passed. * Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, * you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(storage, 1)); // Call the StartWithWebPkiAsync() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the angular controller) and also to complete // the signature on the POST action below (this should not be mistaken with the API access token). var token = await signatureStarter.StartWithWebPkiAsync(); return(token); }
public ActionResult Index(string userfile) { // Get an instance of the PadesSignatureStarter class, responsible for receiving the signature elements and start the // signature process var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) { // Set the unit of measurement used to edit the pdf marks and visual representations MeasurementUnits = PadesMeasurementUnits.Centimeters, // Set the signature policy SignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Set a SecurityContext to be used to determine trust in the certificate chain SecurityContextId = StandardSecurityContexts.PkiBrazil, // Note: By changing the SecurityContext above you can accept certificates from a custom security context created on the Rest PKI website. // Set a visual representation for the signature VisualRepresentation = new PadesVisualRepresentation() { // The tags {{signerName}} and {{signerNationalId}} will be substituted according to the user's certificate // signerName -> full name of the signer // signerNationalId -> if the certificate is ICP-Brasil, contains the signer's CPF Text = new PadesVisualText("Signed by {{signerName}} ({{signerNationalId}})") { // Specify that the signing time should also be rendered IncludeSigningTime = true, // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left HorizontalAlign = PadesTextHorizontalAlign.Left }, // We'll use as background the image in Content/PdfStamp.png Image = new PadesVisualImage(Util.GetPdfStampContent(), "image/png") { // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque). Opacity = 50, // Align the image to the right HorizontalAlign = PadesHorizontalAlign.Right }, // Position of the visual representation. We have encapsulated this code in a method to include several // possibilities depending on the argument passed. Experiment changing the argument to see different examples // of signature positioning. Once you decide which is best for your case, you can place the code directly here. Position = PadesVisualElements.GetVisualPositioning(1) }, }; // If the user was redirected here by UploadController (signature with file uploaded by user), the "userfile" URL argument // will contain the filename under the "App_Data" folder. Otherwise (signature with server file), we'll sign a sample // document. if (string.IsNullOrEmpty(userfile)) { // Set the PDF to be signed as a byte array signatureStarter.SetPdfToSign(Util.GetSampleDocContent()); } else { // Set the path of the file to be signed signatureStarter.SetPdfToSign(Server.MapPath("~/App_Data/" + userfile.Replace("_", "."))); // Note: we're passing the filename argument with "." as "_" because of limitations of ASP.NET MVC } /* Optionally, add marks to the PDF before signing. These differ from the signature visual representation in that they are actually changes done to the document prior to signing, not binded to any signature. Therefore, any number of marks can be added, for instance one per page, whereas there can only be one visual representation per signature. However, since the marks are in reality changes to the PDF, they can only be added to documents which have no previous signatures, otherwise such signatures would be made invalid by the changes to the document (see property PadesSignatureStarter.BypassMarksIfSigned). This problem does not occurr with signature visual representations. We have encapsulated this code in a method to include several possibilities depending on the argument passed. Experiment changing the argument to see different examples of PDF marks. Once you decide which is best for your case, you can place the code directly here. */ //signatureStarter.PdfMarks.Add(PadesVisualElements.GetPdfMark(1)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a 43-character // case-sensitive URL-safe string, which identifies this signature process. We'll use this value to call the // signWithRestPki() method on the Web PKI component (see javascript on the view) and also to complete the signature // on the POST action below (this should not be mistaken with the API access token). var token = signatureStarter.StartWithWebPki(); // The token acquired above can only be used for a single signature attempt. In order to retry the signature it is // necessary to get a new token. This can be a problem if the user uses the back button of the browser, since the // browser might show a cached page that we rendered previously, with a now stale token. To prevent this from happening, // we call the method SetNoCacheHeaders() (in BaseController) which sets HTTP headers to prevent caching of the page. base.SetNoCacheHeaders(); // Render the signature page with the token obtained from REST PKI return View(new Models.PadesSignatureModel() { Token = token, UserFile = userfile }); }