How can I sign a text by certificate in SQL Server and provide PKCS#7 signature? - sql

In my app i need to implement digital signature of some text, extracted from DB data (customer bill, for example), to send a text by e-mail together with it's signature in PKCS#7 format. Both because of high load and data volumes, and a fact that an e-mail app is provided by external developers, it's highly desired to include a text signature in SQL Server resultset, which returns all the data (e-mail attachments) to e-mail app.
The problem is that SQL Server uses x509 v.3 certificate format. It is not a problem while importing certificate and a key - I can convert it to x509 v.3 using OpenSSL before import, it's a one-time deal. But is there a way to convert a SQL Server signature to PKCS#7 format inside SQL Server, or do I have to implement a signing process outside of it?

Related

Using e signature in .net core application with time stamp

I am building an data entry application using .net core.
When adding a new row in my database, I need to allow user to add e signature.
The workflow will be like this, there will be a from eg.(Name,Age,etc.) and a canvas field for e signature.
I will allow users to draw their signatures in this canvas and save this image data along with form data.
When I find the example for the e-signature, I found an example with a timestamp server.
What is the usage of timestamp in e-signature? Do I need to add a new field for timestamp in my database column?
Kindly help me explain what timestamp is and the usage of timestamp in .net core e-signature.
First Question, Why we need timestamp in Digital Signature?
In order to answer this question, we must first understand the risk that comes from a digital signature, Thinking about the workflow for an ink signature. When you sign any legal document, it’s typically done in the presence of a notary. The notary verifies your identity and validates the date and time of the signature. In return, you would also record an entry in a logbook with date and time of the transaction and add a thumbprint.
Now think about implementing this flow in the digital world. When you sign any document with your public key infrastructure (PKI) based digital signature, how do you make sure that there is non-repudiation in place? For example, when a PDF document is digitally signed with your PKI based certificate, it adds the information about the person and date and time of the signature. However, the date and time of this signature is based on the computer’s local time, which can be easily changed or forged. If your certificate is expired or revoked, you could potentially change the local time to make it appear that the certificate is still valid. So, how do you prevent this and trust the digital signature?
You can solve this problem by using Time Stamping Authority (TSA), which uses RFC 3161 Time-Stamp Protocol (TSP) to apply an accurate, trusted timestamp. It is used for proving that the data has not been tampered with and guarantees the data integrity. When TSA is used while signing the document or code, tampering with the timestamp is prevented.
Second Question, the usage of timestamp in Digital Signature
I think there are two methods can achieve it,
The first way is to save Digital Signature to the database, the other way is to save the Digital Signature as a static file(image). When you want to save it in database, you can add a new field for timestamp. When you just want to save Digital Signature as image,You can add timestamps as watermarks to this image.

Can anyone other than web client calculate the fingerprint of a digital certificate? And figure out CA’s private key from fingerprint signature pairs?

I had a random question while trying to understand digital certificate.
From what I understand, a web server sends a CSR to a CA, which contains web server’s RSA public key and identity (subject, CN etc.). CA adds some more information (e.g. issuer, validity dates), signs this CSR with the RSA private key of CA and thus prepares a digital certificate.
More simply, this is what follows -
Create the certificate content (Client’s public key, Subject, Issuer, Validity dates etc.)
Creating HASH of the above certificate content (fingerprint)
Create signature by encrypting only the HASH (not the entire certificate content) and append this signature to the above certificate content and thus prepare a digital certificate.
(kind of like this one - Digital certificate creation
Am I correct in understanding the creation process of a digital certificate?
If that’s so,
the certificate contents (except signature part) seems totally un-encrypted and thereby can be read by anybody between a client and web server. Thus every device between client and webserver should be able to read the fingerprint and signature. Now that –
Fingerprint of certificate (HASH) + CA’s private key = encrypted text (Signature)
Is there a possibility that somebody can take lots and lots of packet trace of certificates transferred, calculate the fingerprint himself for each certs, create a lot of pairs of fingerprints and signature pairs and find out the CA’s private key by some sort of reverse calculation?
Thanks ..
This is not about programming (and I agree to delete this if necessary to close or delete)
Digital signature is NOT "encrypting with the private key". This is a wrong idea that was popular about 40 years ago, but still lingers because people keep copying it. See my https://security.stackexchange.com/questions/159282/can-openssl-decrypt-the-encrypted-signature-in-an-amazon-alexa-request- .
Web servers, and other SSL/TLS servers, and CAs also, are not limited to RSA. Several other signing algorithms are possible, and currently ECDSA is becoming fairly common. It is fairly common for CAs to use the same algorithm for the cert as the subject's key, i.e. to sign a cert containing an RSA key with an RSA key or one containing an ECDSA key with an ECDSA key, but this is not technically necessary (and 1.3 supports separate negotiations for the server or client sigalgs and the certificate sigalgs, which earlier protocols did not).
The fingerprint of a cert, by convention, is the hash of the whole cert including the signature, not the hash of the signed part which is used in the digital signature computation.
But yes, certificates are designed to be public and can be read by anybody. (For TLS 1.3 the certificate transmission is encrypted so a totally passive eavesdropper can't read it, but a minimally active attacker can simply do their own connection and get the cert(s).) Even the signature can be verified by anybody. For RSA only, verifying the signature involves recovering (not decrypting) and comparing the hash, but even without that anyone can compute the hash of the signed part.
For any signature scheme to be considered acceptable in the past 50 years or so, knowing signatures for valid data, even attacker-chosen data, must not allow either recovering the key nor forging a signature for different data (that the attacker wants) which would be just as bad for security. RSA as currently used as acceptable, although one scheme (block type 0) in early PKCS1v1 last century was not. ECDSA is acceptable if appropriately random 'k' values are used, or instead deterministic but key-dependent ones (see RFC6979 and a dozens of Qs on crypto.SX and security.SX where this is ontopic). However, if two ECDSA signatures are known (for known data) using the same key and k the private key can be recovered; there are also numerous existing Qs on this, including on bitcoin.SX because it occurred on some Bitcoin implementations (look for either "same/duplicate k" or "same/duplicate r" because one component of the ECDSA signature, r, is computed directly from the scalar multiplication kG).

iTextSharp not rendering digital signature

I've read the I-TEXT digital signature e-text, and also previous posts answered by MKL (who seems to be the authority along with Bruno on this topic).
essentially I have an Azure app service that gets the digital sig (base 64) and certificate chain from the company's signing API. The company's signing API returns a signature in Base64 along with a certificate chain.
I just want the to insert a signature object/container into the pdf so it will show in the signature panel when an end user opens up the pdf. I prefer to use deferred signing.
I've shifted from chapter 4's "clientseversigning example" to instead Deferred Signing in MKL's "How to create a PDF signature without knowing the signer certificate early".
The Company API returns a "plain" signature, that I am pretty sure, and also returns a chain of 3 string certificates.
I should note I do have the root and sub certs in advance (2 .cer files) but I am not using them in "prepping" the pdf for hashing right now since the deferred signing example doesn't make use of them obviously. For the container construction code (after getting the response from the Company API), I use the 3 certs chain returned from the company API, but I also tried it with the 2 .cer files, to no avail.
The only difference between my code and the one in the example is instead of byte[] certificateBytes = THE_RETRIEVED_CERTIFICATE_BYTES; X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(certificateBytes); I build 3 x509Certificates (one for each string in the chain returned from the Company API.
Sadly things wont work, I get these errors in Acrobat: Signature is invalid, There are errors in the formatting or information contained in this signature, signature's identity has not yet been verified, signing time is from the clock on the signer's computer...also if I click Certificate details just below of this error in Acrobat it is blank. This was pretty much the errors I was getting when trying the "clientserversigning example"
I am trying really hard and wondering what it could be... should I try modifying the estimated size from 12000 and bump it up? or the errors I am getting in Acrobat, maybe they are hinting the certificate chain from the Company API is not being picked up by the signing deferral container construction code ... I am struggling but any tips would be so greatly appreciated
Evan
Just to clarify, I am following chapter 4's clientserversigningexample but I am getting the following once my pdf is recreated with the signature from the company API
Its saying 1) there are errors in the formatting of information
2) signer's identity has not been verified
3) signing time is from the clock on the signer's computer
now as far as "prepping" the pdf before hashing it to send for signing...I don't see anything in the ClientSigning example that specifically preps it, can I assume the IText library is prepping it under the hood?
In your question and in your comments to it you appear to be in particular interested in
whether or not one can use a signature API that returns the certificates only together with the signature, and
when to to deferred signing.
Can You Use a Signature API That Provides the User Certificate Only After Signing
To answer this one first has to clarify what kind of signatures the signature API in question creates, plain signature values (e.g. PKCS#1 RSA signatures) or full-fledged CMS signature containers.
If it creates full-fledged CMS signature containers, you can create signatures following arbitrary signature profiles as long as the signature containers follow the requirements for them (which they often do). They only restriction you have is that you cannot have information from the signer certificate in the signature visualization because that visualization is defined in the signed data of the PDF.
If it only creates plain signature values, the best you can do is create and embed simple CMS containers that don't contain pointers to the signer certificate in the signed attributes (if they have any signed attributes as all to start with). Many signature policies of interest do require such pointers, but at least Adobe Reader accepts signatures without.
If you are in this situation and want to try creating signatures with such simple signature containers, you may want to use the code from this answer, section "How to create a PDF signature without knowing the signer certificate early".
When to Use Deferred Signing
The difference between deferred signing and other iText signing calls is not that deferred signing requires less information (compared to ExternalContainer signing).
In contrast to the other iText signing methods, signDeferred re-uses the outermost existing, filled signature field of the PDF to sign and merely replaces the signature container therein.
The method name is derived from the most common use case it’s used for:
In a first step a signature field is (probably first created and then) filled using signExternalContainer with an IExternalSignatureContainer implementation that calculates the document hash to be signed but does not return the final CMS container yet, merely some (usually) empty array. The generated PDF with a filled signature field (albeit without the final signature container) is then temporarily stored (in the file system or a database).
In a second step a signature container for the determined document hash is requested and (probably asynchronously) awaited.
In a final step signDeferred is used to inject the retrieved signature container into the PDF prepared in the first step.
This deferred signing process usually is preferred in setups in which the second step, the signature container creation and retrieval, can take longer than one wants to keep the resources blocked which are required for the document in signing. This includes in particular signatures generated by remote servers or clients, especially if that signing process awaits some third party clearance or activation.

proof of API response

Let's say I have access to an https weather API.
Let's say I query its health status on thursday 17/08/2017 23h30 and the API replies OK (simple OK http code).
As a client, I need to prove in the future that the service actually responded me this data.
I'm thinking to asking the API to add a crypto signature of the data sent + timestamp, in order to prove they actually responded OK at that specific time.
Is it overkill? Is there a more simple way of doing it?
A digital signature containing current date/time or even adding a time stamp issued by a third party time stamp authority is an appropriate way to ensure that the content was actually issued on a date
In general, implementing a digital signature system on HTTP requests is not so simple and you have to consider many elements:
What content will you sign: headers, payload, attachments?
Is it binary content or text? Because the algorithms and signature formats will be different
In case of text you must canonicalize the content to avoid encoding problems when you verify the signature on the client side. Also you need to define a signature algorithm to compute the content to sign
Do you also need to sign the attachments when they are sent via streams?. How are you going to handle big files?
How are you going to attach the signature to the https response: special header, additional attribute in the payload?
How is the server going to distribute the signing certificate? You should include it in a truststore on the client
But, if you only want to proof that a service response was OK/FAIL, then the server just need to add a digital signature over the payload (or computed on a concatenation of the headers) but if you want to implement something more complex I suggest you take a look at the Json Web Signature (JWS)

PDF Signature digest

I have a quick question about calculating the digest of a PDF document to use for a digital signature (somewhat related to one of my earlier questions, I'm trying to figure out why you would need to know a client's certificate to create the correct digest).
In Adobe's documentation about the PDF format the following is specified:
A byte range digest shall be computed over a range of bytes in the file, that shall be indicated by the
ByteRange entry in the signature dictionary. This range should be the entire file, including the signature
dictionary but excluding the signature value itself (the Contents entry).
So at this point things seem fairly simple, just digest everything except the /Contents entry in the /Sig dictionary. The actual data in the /Contents entry is specified as followed:
For public-key signatures, Contents should be either a DER-encoded
PKCS#1 binary data object or a DER-encoded PKCS#7 binary data
object.
So still no problems, I can (probably) generate the digest, reserve space for the /Contents entry and attach this PKCS#7 object later on. The confusion starts when I read the following:
Revocation information is a signed attribute, which means that the
signing software must capture the revocation information before signing. A similar requirement applies to the
chain of certificates. The signing software must capture and validate the certificate's chain before signing.
So the thing I'm not quite getting: Apparently the /Contents entry (containing the certificate and signed digest) is not digested, yet the chain of certificates is a signed attribute (and thus needs to be digested?).
I would appreciate it if someone could further specify exactly what is digested, and perhaps better explain the signed attributes to me. The main question that I want to answer is: Can I actually create a signable digest without knowing someone's certificate beforehand? (I'm working with a pkcs7 detached signature)
In short:
Can I actually create a signable digest without knowing someone's certificate beforehand?
In case of SubFilter ETSI.CAdES.detached or adbe.pkcs7.detached you can create the document digest without knowing someone's certificate beforehand.
You usually, though, have to know the signer certificate before starting to generate the CMS signature container to embed into the PDF.
In detail:
(Beware, the following is somewhat simplified.)
I can (probably) generate the digest, reserve space for the /Contents entry and attach this PKCS#7 object later on.
If you first reserve space and thereafter generate the digest, this indeed is how things are done.
The confusion starts when I read the following:
Revocation information is a signed attribute, which means that the signing software must capture the revocation information before signing. A similar requirement applies to the chain of certificates. The signing software must capture and validate the certificate's chain before signing.
So the thing I'm not quite getting: Apparently the /Contents entry (containing the certificate and signed digest) is not digested, yet the chain of certificates is a signed attribute (and thus needs to be digested?).
I would appreciate it if someone could further specify exactly what is digested, and perhaps better explain the signed attributes to me.
The main fact one has to be aware of is that in case of PKCS#7/CMS signature containers signing usually does not merely include one hash calculation but at least two!
The first hash, the document hash, is indeed calculated for the entire file, including the signature dictionary but excluding the signature value itself (the Contents entry) (you might want to read this answer for more details).
But this is not the hash immediately used when applying the signature algorithm.
During the generation of the PKCS#7/CMS signature container (unless in its most primitive form) you create a structure called "signed attributes".
You fill this structure with multiple attributes (name-value-pairs), among them the already calculated document hash but also others, e.g. the Adobe-style revocation information you read about.
When you have finished creating that structure, you hash this structure and generate a signature for it.
You then can put together the PKCS#7/CMS signature container using these signed attributes, the signature, and some more information not signed by this signature, e.g. certificates, signature time stamps, ...
For more details concerning the signature container read this answer.
Finally you embed this signature container into the reserved space in the PDF.
The main question that I want to answer is: Can I actually create a signable digest without knowing someone's certificate beforehand? (I'm working with a pkcs7 detached signature)
In case of SubFilter ETSI.CAdES.detached or adbe.pkcs7.detached you can create the document digest without knowing someone's certificate beforehand.
Depending on the CMS signature profile, though, you usually have to know the signer certificate before starting to generate the signature container because many profiles require the presence of a signed attribute referencing the signer certificate.
Clarifications:
The OP asked some follow-up questions in a comment:
1.: One of the signed attributes is the document hash(without the /contents), so if I understand correctly this is the unsigned hash?
As the "signed attributes" eventually are hashed and signed, that document hash therein is not immediately, directly signed but it is indirectly signed as part of this structure of attributes. So I wouldn't call it unsigned...
In the end when the user really generates a signature, he signs the hash of the PKCS#7 object?
No, the hash of the "Signed attributes" structure which is only a part of the PKCS#7 object, not all of it. There are multiple parts of the PKCS#7/CMS object which are unsigned.
Does the /Contents entry still have a PKCS#7 object that's actually readable for us? (To extract certificates etc for verification)
The Contents entry does contain a full-fledged PKCS#7/CMS signature container object as a binary string. Thus, yes, you can read it (by reading the value of that binary string) and (if you have code that knows how to parse such a signature container) extract information from it.
Beware, though, the signature container may not contain all data required for verification: E.g., if you verify using the chain (not shell) validation model, you might have to extract the signing time from the respective PDF signature dictionary entry.
When verifying a signature, do we simply extract the embedded PKCS#7 object, recalculate the digest, recalculate the digest of the PKCS#7 object and verify this against the signature using the certificate we get from the PKCS#7 object?
You obviously also have to calculate the digest of the signed PDF byte ranges and compare that value with the signed attribute containing the original document digest.(You might have meant that by recalculate the digest.)
As mentioned in the answer to 3, you might have to retrieve additional information from the PDF for use in the PKCS#7 verification.
Furthermore you say the certificate we get from the PKCS#7 object - please be aware that the PKCS#7/CMS signature container may contain multiple certificates. You have to find the correct one. The CMS SignerInfo SignerIdentifier and the ESS signed attributes shall be used for that.
Furthermore you also have to verify validity and trust of the signer certificate.
Is there any good documentation on what authenticated attributes there are?
You can start reading
section 11 "Useful Attributes" of RFC 3852 or RFC 5652: basic CMS
section 12.8 of ISO 32000-1: basic PDF
all of RFC 5126: CAdES
ETSI TS 102778, especially part 2, part 3, and part 4: PAdES