public IHttpActionResult Start(SignatureStartRequest request) { byte[] toSignBytes, transferData; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate var cert = PKCertificate.Decode(request.Certificate); // Instantiate a PadesSigner class var padesSigner = new PadesSigner(); // Set the PDF to sign, which in the case of this example is a fixed sample document if (!string.IsNullOrEmpty(request.FileId)) { padesSigner.SetPdfToSign(Storage.GetFile(request.FileId)); } else { padesSigner.SetPdfToSign(Storage.GetSampleDocContent()); } // Set the signer certificate padesSigner.SetSigningCertificate(cert); // Set the signature policy padesSigner.SetPolicy(getSignaturePolicy()); // Set the signature's visual representation options (optional) padesSigner.SetVisualRepresentation(getVisualRepresentation(cert)); // Generate the "to-sign-bytes". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy, as well as the "transfer data", // a byte-array that will be needed on the next step. toSignBytes = padesSigner.GetToSignBytes(out signatureAlg, out transferData); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. return(new ResponseMessageResult(Request.CreateResponse(HttpStatusCode.BadRequest, new ValidationErrorModel(ex.ValidationResults)))); } // Create response with some informations that we'll use on Complete action and on client-side. var response = new SignatureStartResponse() { // The "transfer data" for PDF signatures can be as large as the original PDF itself. Therefore, we mustn't use a hidden field // on the page to store it. Here we're using our storage mock (see file Classes\Storage.cs) to simulate storing the transfer data // on a database and saving on a hidden field on the page only the ID that can be used later to retrieve it. Another option would // be to store the transfer data on the Session dictionary. TransferDataFileId = Storage.StoreFile(transferData), // Send to the javascript the "to sign hash" of the document (digest of the "to-sign-bytes") and the digest algorithm that must // be used on the signature algorithm computation ToSignBytes = toSignBytes, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(Ok(response)); }
public IHttpActionResult Start(SignatureStartRequest request) { byte[] toSignHash, transferData; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate var cert = PKCertificate.Decode(request.Certificate); // Instantiate a XmlElementSigner class var signer = new XmlElementSigner(); // Set the data to sign, which in the case of this example is a fixed sample document signer.SetXml(Storage.GetSampleNFeContent()); // static Id from node <infNFe> from SampleNFe.xml document signer.SetToSignElementId("NFe35141214314050000662550010001084271182362300"); // Set the signer certificate decoded signer.SetSigningCertificate(cert); // Set the signature policy signer.SetPolicy(getSignaturePolicy()); // Generate the "to-sign-hash". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy. As well as the "transfer data", // a byte-array that will be needed on the next step. toSignHash = signer.GenerateToSignHash(out signatureAlg, out transferData); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. return(new ResponseMessageResult(Request.CreateResponse(HttpStatusCode.BadRequest, new ValidationErrorModel(ex.ValidationResults)))); } // Create response with some informations that we'll use on Complete action and on client-side. var response = new SignatureStartResponse() { // The "transfer data" for Xml signatyures are not so big. Therefore, we can easily send it as one of // response fields. TransferData = transferData, // Send to the javascript the "to sign hash" of the document and the digest algorithm that must // be used on the signature algorithm computation ToSignHash = toSignHash, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(Ok(response)); }
public IHttpActionResult Start(SignatureStartRequest request) { byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate var cert = PKCertificate.Decode(request.Certificate); // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document if (!string.IsNullOrEmpty(request.FileId)) { cadesSigner.SetDataToSign(Storage.GetFile(request.FileId)); } else { cadesSigner.SetDataToSign(Storage.GetSampleDocContent()); } // Set the signer certificate cadesSigner.SetSigningCertificate(cert); // Set the signature policy cadesSigner.SetPolicy(getSignaturePolicy()); // Generate the "to-sign-bytes". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. return(new ResponseMessageResult(Request.CreateResponse(HttpStatusCode.BadRequest, new ValidationErrorModel(ex.ValidationResults)))); } // Create response with some informations that we'll use on Complete action and on client-side. var response = new SignatureStartResponse() { // Send to the javascript the "to sign hash" of the document and the digest algorithm that must // be used on the signature algorithm computation ToSignBytes = toSignBytes, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(Ok(response)); }
public IHttpActionResult Start(SignatureStartRequest model) { byte[] toSign; SignatureAlgorithm signatureAlg; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document cadesSigner.SetDataToSign(Util.GetSampleDocContent()); // Decode the user's certificate and set as the signer certificate cadesSigner.SetSigningCertificate(PKCertificate.Decode(model.Certificate)); // Set the signature policy cadesSigner.SetPolicy(getPolicy()); // Generate the "to-sign-bytes". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy. toSign = cadesSigner.GenerateToSignBytes(out signatureAlg); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. return Ok(new SignatureStartResponse() { Success = false, Message = "A validation error has occurred", ValidationResults = ex.ValidationResults.ToString() }); } // On the next step (Complete action), we'll need once again the signer's certificate and the // "to-sign-bytes" (besides from the document to be signed and the policy). We'll store these // values on the database and return to the page an identifier that will be later used to locate // these values again. SignatureProcess signatureProcess; using (var dbContext = new DbContext()) { signatureProcess = SignatureProcess.Create(); signatureProcess.CadesSignerCertificate = model.Certificate; signatureProcess.CadesToSign = toSign; dbContext.SignatureProcesses.Add(signatureProcess); dbContext.SaveChanges(); } // Send back to the page: // - The identifier that we'll later use to locate the user's certificate and "to-sign-bytes" // - The "to-sign-bytes" // - The OID of the digest algorithm to be used during the signature operation var response = new SignatureStartResponse() { Success = true, ProcessId = signatureProcess.Id, ToSign = toSign, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return Ok(response); }