Subject Publish Key Pinning for HTTPs - ssl-certificate

I am implementing the SPKI Pinning to my mobile apps and i wonder if the Subject Publish Key will change when I renew it with another CA?
I still use the same CSR to generate the cert. People say that the Public Key will be the same if we use the same Certificate Signing Request file (CRS), But I'm not sure if CA is also a factor.

Short answer is: no, it shouldn't change, provided you did things properly.
It is recommended that when you specify a SPKI HTTP header you should provide at least two Subject Public Key Information (SPKI) fingerprint of private keys in your control (one for production and other for backup). Now, as reported here, it is a common practice to specify the SPKI fingerprint of well known CA in the case of private key loss, but it renders HPKP invalid because if the CA is compromised then you are basically saying "trust the CA issued certificates". That is why recommendation is to provide the SPKI fingerprint of your own public keys: one for common usage and another in case of private key loss.
Thus, provided you are specifying in the SPKI HTTP header of your own public key, whenever you generate a new certificate with another CA (either with the same CSR or a new one) your public key will be the same and the SPKI will still be valid.

Related

How a client verifies a certificate validity? [duplicate]

What is the series of steps needed to securely verify a ssl certificate? My (very limited) understanding is that when you visit an https site, the server sends a certificate to the client (the browser) and the browser gets the certificate's issuer information from that certificate, then uses that to contact the issuerer, and somehow compares certificates for validity.
How exactly is this done?
What about the process makes it immune to man-in-the-middle attacks?
What prevents some random person from setting up their own verification service to use in man-in-the-middle attacks, so everything "looks" secure?
Here is a very simplified explanation:
Your web browser downloads the web server's certificate, which contains the public key of the web server. This certificate is signed with the private key of a trusted certificate authority.
Your web browser comes installed with the public keys of all of the major certificate authorities. It uses this public key to verify that the web server's certificate was indeed signed by the trusted certificate authority.
The certificate contains the domain name and/or ip address of the web server. Your web browser confirms with the certificate authority that the address listed in the certificate is the one to which it has an open connection.
Your web browser generates a shared symmetric key which will be used to encrypt the HTTP traffic on this connection; this is much more efficient than using public/private key encryption for everything. Your browser encrypts the symmetric key with the public key of the web server then sends it back, thus ensuring that only the web server can decrypt it, since only the web server has its private key.
Note that the certificate authority (CA) is essential to preventing man-in-the-middle attacks. However, even an unsigned certificate will prevent someone from passively listening in on your encrypted traffic, since they have no way to gain access to your shared symmetric key.
You said that
the browser gets the certificate's issuer information from that
certificate, then uses that to contact the issuerer, and somehow
compares certificates for validity.
The client doesn't have to check with the issuer because two things :
all browsers have a pre-installed list of all major CAs public keys
the certificate is signed, and that signature itself is enough proof that the certificate is valid because the client can make sure, on his own, and without contacting the issuer's server, that that certificate is authentic. That's the beauty of asymmetric encryption.
Notice that 2. can't be done without 1.
This is better explained in this big diagram I made some time ago
(skip to "what's a signature ?" at the bottom)
It's worth noting that in addition to purchasing a certificate (as mentioned above), you can also create your own for free; this is referred to as a "self-signed certificate". The difference between a self-signed certificate and one that's purchased is simple: the purchased one has been signed by a Certificate Authority that your browser already knows about. In other words, your browser can easily validate the authenticity of a purchased certificate.
Unfortunately this has led to a common misconception that self-signed certificates are inherently less secure than those sold by commercial CA's like GoDaddy and Verisign, and that you have to live with browser warnings/exceptions if you use them; this is incorrect.
If you securely distribute a self-signed certificate (or CA cert, as bobince suggested) and install it in the browsers that will use your site, it's just as secure as one that's purchased and is not vulnerable to man-in-the-middle attacks and cert forgery. Obviously this means that it's only feasible if only a few people need secure access to your site (e.g., internal apps, personal blogs, etc.).
I KNOW THE BELOW IS LONG, BUT IT IS DETAILED, YET SIMPLIFIED ENOUGH. READ CAREFULLY AND I GUARANTEE YOU'LL START FINDING THIS TOPIC IS NOT ALL THAT COMPLICATED.
First of all, anyone can create 2 keys. One to encrypt data, and another to decrypt data. The former can be a private key, and the latter a public key, AND VICERZA.
Second of all, in simplest terms, a Certificate Authority (CA) offers the service of creating a certificate for you. How? They use certain values (the CA's issuer name, your server's public key, company name, domain, etc.) and they use their SUPER DUPER ULTRA SECURE SECRET private key and encrypt this data. The result of this encrypted data is a SIGNATURE.
So now the CA gives you back a certificate. The certificate is basically a file containing the values previously mentioned (CA's issuer name, company name, domain, your server's public key, etc.), INCLUDING the signature (i.e. an encrypted version of the latter values).
Now, with all that being said, here is a REALLY IMPORTANT part to remember: your device/OS (Windows, Android, etc.) pretty much keeps a list of all major/trusted CA's and their PUBLIC KEYS (if you're thinking that these public keys are used to decrypt the signatures inside the certificates, YOU ARE CORRECT!).
Ok, if you read the above, this sequential example will be a breeze now:
Example-Company asks Example-CA to create for them a certificate.
Example-CA uses their super private key to sign this certificate and gives Example-Company the certificate.
Tomorrow, internet-user-Bob uses Chrome/Firefox/etc. to browse to https://example-company.com. Most, if not all, browsers nowadays will expect a certificate back from the server.
The browser gets the certificate from example-company.com. The certificate says it's been issued by Example-CA. It just so happens to be that Bob's OS already has Example-CA in its list of trusted CA's, so the browser gets Example-CA's public key. Remember: this is all happening in Bob's computer/mobile/etc., not over the wire.
So now the browser decrypts the signature in the certificate. FINALLY, the browser compares the decrypted values with the contents of the certificate itself. IF THE CONTENTS MATCH, THAT MEANS THE SIGNATURE IS VALID!
Why? Think about it, only this public key can decrypt the signature in such a way that the contents look like they did before the private key encrypted them.
How about man in the middle attacks?
This is one of the main reasons (if not the main reason) why the above standard was created.
Let's say hacker-Jane intercepts internet-user-Bob's request, and replies with her own certificate. However, hacker-Jane is still careful enough to state in the certificate that the issuer was Example-CA. Lastly, hacker-Jane remembers that she has to include a signature on the certificate. But what key does Jane use to sign (i.e. create an encrypted value of the certificate main contents) the certificate?????
So even if hacker-Jane signed the certificate with her own key, you see what's gonna happen next. The browser is gonna say: "ok, this certificate is issued by Example-CA, let's decrypt the signature with Example-CA's public key". After decryption, the browser notices that the certificate contents don't match at all. Hence, the browser gives a very clear warning to the user, and it says it doesn't trust the connection.
The client has a pre-seeded store of SSL certificate authorities' public keys. There must be a chain of trust from the certificate for the server up through intermediate authorities up to one of the so-called "root" certificates in order for the server to be trusted.
You can examine and/or alter the list of trusted authorities. Often you do this to add a certificate for a local authority that you know you trust - like the company you work for or the school you attend or what not.
The pre-seeded list can vary depending on which client you use. The big SSL certificate vendors insure that their root certs are in all the major browsers ($$$).
Monkey-in-the-middle attacks are "impossible" unless the attacker has the private key of a trusted root certificate. Since the corresponding certificates are widely deployed, the exposure of such a private key would have serious implications for the security of eCommerce generally. Because of that, those private keys are very, very closely guarded.
if you're more technically minded, this site is probably what you want: http://www.zytrax.com/tech/survival/ssl.html
warning: the rabbit hole goes deep :).

Digital signature man in the middle attack prevention

I have client-side generated a digital signature(JavaScript). The signature is then verified on Java back end. To verify the signature I am passing to the backend - (signature value, public key and message for verification). So far so good, but then the question arises - What if someone performs a man in the middle attack? He can easily generate a signature and send his - (signature value, public key and message.). So in a sense, this makes my current implementation not secure enough.
How can I avoid this? As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority). However, in my case, I am doing this as a final project in university and I am not sure how to approach this problem.
Should I generate the public key certificate on the client side and send them along with the public key? Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?
What if someone performs a man in the middle attack
A MITM could replace the signature and the public key
How can I avoid this?
Mainly use SSL/TLS and/or...
As far as I researched I have to verify that the public key sent is coming from the appropriate client and this is done through CA (Certificate Authority)
If you use a Certificate Authority, each certificate is signed with the private key of the root CA certificate (or a subCA), so a MITM can not create a valid certificate because he does not own the root private key.
At server side, you can validate that the signature has been performed with a private key that corresponds to a certificate issued by the CA. Note that in this case you are working with certificates, not just with public keys ( a certificate envelopes a public key).
I am doing this as a final project in university and I am not sure how to approach this problem.
You have explained your solution but not the background. I mean why do you decided you need a digital signature? without that information I can not advise you.
Should I generate the public key certificate on the client side and send them along with the public key?
Read my previous comment
Is it possible to generate self-signed-certificates on client-side and then verify it on the back-end?
Yes, of course. You can generate a key pair at client side and associate the public key with the user's account during the registration process (using a secure channel)
This way you do not even need a password. The digital signature with the private key is the authentication proof. Using a CA is optional. The CA could issue a certificate containing the public key, but fot this scenario is not required

Encrypting a file using a private key and public key

I am a developer with very little experience of encryption. I am trying to learn more about Encryption and specifically SSL in my spare time.
Say a trusted company has a file (notepad) that contains a load of personal and confidential information. Say I wanted to ask them to send this information to a me to analyze. How would I do this?
My research is telling me that I would have to:
1) Create a self signed certificate
2) Generate the public and private key
3) Issue the public key to the trusted company and keep the private key
4) Ask the company to encrypt the information using the public key and then send it to me
5) Decrypt the file using the private key
Is that correct? How would I do this?
Should the certificate be signed by a Certificate Authority in this case as I would manually be issuing the public key to the trusted company (they know it comes from me).
As I said I am relatively new to this subject.
SSL is a protocol for encrypting network connections. It's not really relevant for manually encrypting and decrypting files. (It's also insecure and deprecated; TLS should be used instead.)
If you want to manually encrypt and decrypt files, yes, you could use a self-signed certificate and just give the public key to the company that'll send the file. However, you have to make sure to give them the public key in a way that can't be intercepted — such as physically handing it over on a flash drive, not emailing it — or you're vulnerable to a man-in-the-middle attack: someone could intercept the public key and give the company a different one instead. (If that happened, the company would unknowingly be encrypting the file for the attacker to decrypt, and the attacker would then re-encrypt the file with the real public key and send it along to you.)
If you're doing this manually and you deliver the public key in a secure way, you don't need to involve a certificate authority. The purpose of a certificate authority is to vouch for the authenticity of a certificate when it's delivered over an insecure channel. For example, when you visit stackoverflow.com, your browser gets a certificate (with a public key) from the web server. Since this certificate wasn't personally given to you by SO staff, how do you know that the web server is the real stackoverflow.com, not a man-in-the-middle attacker intercepting your connection in order to hijack your account? The website's certificate is signed by a certificate authority — DigiCert, currently — that says DigiCert has verified that it's real. Your browser is configured to trust that signature from DigiCert, because the browser developers have verified that the company is trustworthy.
PGP and GPG are good tools for securely exchanging encrypted files. They use a "web-of-trust" model based on securely exchanging certificates, rather than relying on a certificate authority.

How CSRs fit into the SSL Certificate Lifecycle

So you decide to go with a CA like VeriSign (or whoever, doesn't matter for this question). You apply for an SSL certificate from them. This CA invesitgates you to make sure the information you provided in your application is truthful and that you are who you say you are. Finally, the CA grants you an SSL certificate.
I am really confused about CSRs, what they are, who issues them, who responds to them, and where/how they fit into the scenario described above:
Certificate-Signing Request: To me this means "A request to sign a certificate." So, who makes the request? Who signs it? Why is this necessary?
When is a CSR generated? When is it acted upon? What subsequent procedures/actions does the CSR hold up (while it is in the process of being signed)?
How does the CSR fit into the scenario described above?
Thanks in advance!
The name is confusing - it's not a certificate signing request but a request for certificate. When you need to acquire a certificate from the CA, you do the following:
On the client side you generate a keypair (a public and a private key). You save the private key in a safe place, and also you (your generator software) creates a certificate request usually in PKCS#10 format (there's one more format used, which is more rare). This request is a binary ASN.1 sequence of various fields which are filled by you and your software. The request also includes your public key.
Next the certificate request is sent to the CA (usually transmitted over HTTPS). The CA handles the request by parsing it and creating a certificate with your public key embodied. Some information provided in the request (mainly your name / organization name, called Subject Name) is copied to the certificate. The certificate is signed with CA's private key.
The procedure can be automated but normally should involve human validation as you will be required to provide identification information (company documents, your documents etc).
Finally you receive a signed certificate from the CA. You can combine it with the private key or you can keep them separated.

How does a ROOT CA verify a signature?

Say when using https, browser makes a request to the server and server returns its certificate including public key and the CA signature.
At this point, browser will ask its CA to verify if the given public key really belongs to the server or not?
How is this verification done by the Root cert on the browser?
To give an example:
Say serverX obtained a certificate from CA "rootCA". Browser has a copy of rootCA locally stored. When the browser pings serverX and it replies with its public key+signature. Now the root CA will use its private key to decrypt the signature and make sure it is really serverX?
is it how it works?
Your server creates a key pair, consisting of a private and a public key. The server never gives out the private key, of course, but everyone may obtain a copy of the public key. The public key is embedded within a certificate container format (X.509). This container consists of meta information related to the wrapped key, e.g. the IP address or domain name of a server, the owner of that server, an e-mail contact address, when the key was created, how long it is valid, for which purposes it may be used for, and many other possible values.
The whole container is signed by a trusted certificate authority (= CA). The CA also has a private/public key pair. You give them your certificate, they verify that the information in the container are correct (e.g. is the contact information correct, does that certificate really belong to that server) and finally sign it with their private key. The public key of the CA needs to be installed on the user system. Most well known CA certificates are included already in the default installation of your favorite OS or browser.
When now a user connects to your server, your server uses the private key to sign some random data, packs that signed data together with its certificate (= public key + meta information) and sends everything to the client. What can the client do with that information?
First of all, it can use the public key within the certificate it just got sent to verify the signed data. Since only the owner of the private key is able to sign the data correctly in such a way that the public key can correctly verify the signature, it will know that whoever signed this piece of data, this person is also owning the private key to the received public key.
But what stops a hacker from intercepting the packet, replacing the signed data with data he signed himself using a different certificate and also replace the certificate with his own one? The answer is simply nothing.
That's why after the signed data has been verified (or before it is verified) the client verifies that the received certificate has a valid CA signature. Using the already installed public CA key, it verifies that the received public key has been signed by a known and hopefully trusted CA. A certificate that is not signed is not trusted by default. The user has to explicitly trust that certificate in his browser.
Finally it checks the information within the certificate itself. Does the IP address or domain name really match the IP address or domain name of the server the client is currently talking to? If not, something is fishy!
People may wonder: What stops a hacker from just creating his own key pair and just putting your domain name or IP address into his certificate and then have it signed by a CA? Easy answer: If he does that, no CA will sign his certificate. To get a CA signature, you must prove that you are really the owner of this IP address or domain name. The hacker is not the owner, thus he cannot prove that and thus he won't get a signature.
But what if the hacker registers his own domain, creates a certificate for that, and have that signed by a CA? This works, he will get it CA signed, it's his domain after all. However, he cannot use it for hacking your connection. If he uses this certificate, the browser will immediately see that the signed public key is for domain example.net, but it is currently talking to example.com, not the same domain, thus something is wrong again.
The server certificate is signed with the private key of the CA. The browser uses the public key of the CA to verify the signature. There is no direct communication between browser and CA.
The important point is that the browser ships with the public CA key. So the browser knows beforehand all CAs it can trust.
If you don't understand this, look up the basics of Asymmetric Cryptography and Digital Signatures.
Certs are based on using an asymmetric encryption like RSA. You have two keys, conventionally called the private and public keys. Something you encrypt with the private key can only be decrypted using the public key. (And, actually, vice versa.)
You can think of the cert as being like a passport or drivers license: it's a credential that says "this is who I am; you can trust it because it was given to me by someone (like Verisign) you trust." This is done with a "signature", which can be computed using the certificate authority's public key. If the data is what the CA got originally, you can verify the cert.
The cert contains identifying information about the owner of the cert. When you receive it, you use the combination of the key you know from your trusted authority to confirm that the certificate you received is valid, and that you can therefore infer you trust the person who issued the cert.
Your browser does not ask the CA to verify, instead it has a copy of the root certs locally stored, and it will use standard cryptographic procedure to verify that the cert really is valid.
This is why when you self sign a certificate your certificate is not valid, eventhough there technically is a CA to ask, you could off course copy the self signed CA to your computer and from then on it would trust your self signed certifications.
CACert.org has this same issue, it has valid certificates but since browsers don't have its root certs in their list their certificates generate warnings until the users download the root CA's and add them to their browser.