Understanding how certificates work in a client-server interaction - https

So, I'm trying to understand how certificates really, really work - I haven't been able to find what exactly I'm looking for on google so I'm phrasing it my way... If there's a straightforward link that you think might help me - please post it and I will delete this question.
I understand that when the client(say, a browser) makes a request to a website, it verifies the identity of the website by checking its certificate. Self signed certificates are discouraged and certificates from the Certificate Authority (and its branches) are the real deal. Now that the identity has been verified, the request is processed by the server and the response is sent to the client and now the user (a human being) can see that green lock sign on their browser next to the URL. Did I sum this up correctly? And this response is encrypted and will be decrypted by the browser/client?
In the case of SSO (single sign on) flows - when SAML assertions are "digitally signed" - what exactly does this mean? And how does the above mentioned certificates help in that?
I've just got too many concepts all mixed up in my head and was looking for clarity understanding systems and security and TLS.

First of all this is all about asymmetric cryptography. This allows to encrypt the message with one key and decrypt with another. Why is this helpful.
Secure interaction
You can send a message to your server using the public key of that server. Thus you can be sure that nobody else (except of that server) would be able to decrypt that message
Digital signing
You can encrypt a digest of a message with your private key and anyone will be able to check if that was you by decrypting your "signature" with your public key.
At what stage the certificate is involved
Both above cases have a pitfall. You cannot be really sure that the public key that the server provides you is really a key of the party you trust to. The same with signatures. You cannot be sure that the public key you have just successfully used to verify a signature is really a key of a person you expect to sign your contract.
Certificate is a bundle of a public key and the information about the holder of the key pair. This bundle is digitally signed with the private key of CA.
What is the end to end process
Let's consider https case. Your client says to a server "Hey I want to use https protocol". This is the point where asymmetric cryptography is involved. You use server's public key to encrypt a symmetric key (since the asymmetric cryptography is somewhat expensive, it is used only when symmetric key is being negotiated) that will be used for encrypting traffic.
But how can you be sure you can trust that server. Actually what server sends you is not just a key but a certificate. You take the certificate and verify that the server name specified in the cert is actually what you used in your address bar. You also verify the signature of CA using that CA's public key.
Certification chain
Public key of CA that has signed the server certificate might also require verification. Such verification is performed in the same way as explained above. The chain has to eventually stop at the certificate that you absolutely trust. Such certificates are stored at so called trust store.
So this is how ssl works. Digitally signed SAML assertions work in the very similar way. They deliver certificates which you can validate and use the public keys extracted from them for validating the signature of assertions.

Related

Is a world known CA certificate compulsory for a https site?

I want my site to be secure using HTTPS protocols. I managed to make a self-signed key to be trustedCertEntry as I made my own CA certificate, with different CN, which I used to sign my own private certificate.
It works smooth testing it with openssl with something like:
openssl s_client -connect www.mydomain.com:80 -tls1 -state
Thus, browser doesn't report a certificate self-signed error, as it sees a different CA.
But I get a SEC_ERROR_UNKNOWN_ISSUER error. Still it seems logical to me as nobody knows me as a CA. It is supposed to work if user adds exception for me.
I thought this trick was acceptable and it was like many https compliant sites were working, as you may visit a unknown site and you want to encrypt communications from 3rd party watchers but trust that page.
After trying to get a clear response for it, beyond coding that I will find resources, my question is:
If I want to have a site, for which the users don't have to add an exception in the first visit, do I have to get a certificate from a "world-known" CA? Or am I missing a solution for self-signing my certificate with my own CA certificate?
Technically speaking, the answer is: Yes, you will have to get a certificate from a CA that is trusted by your users' browsers via a chain of intermediary CA's that ends at an inherently trusted root CA. The accepted answer to this question explains how it works: SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate?
Having said that, if your "only" concern is to provide encrypted connections, you might be able to leverage the Let's Encrypt CA, which provides free certificates for that purpose. Those certificates will be only domain-validated, which provides a weaker kind of assurance of identity than, for example, an Extended Validation Certificate.
Depending on the browser used, there will be minimal difference in user experience between DV and EV certificates. For Safari, the user will see a grey padlock in the address bar for the lower assurance DV-backed sites, like this:
and a green padlock when higher identity assurance is provided, like this:
Whether the former is good enough for you (or your customers) depends on your situation.
In case you want to understand what "inherently trusted" actually means for web browsers, see this blog post: Who your browser trusts, and how to control it.

Need some insight on Https

Excuse me if this question is really naive, but I searched as much as I could without being able to find relevant answers.
I spent the last three days trying to understand how https works.
All I knew before these days is how symmetric and asymmetric cryptography works.
It was about time for me to understand how these two are applied on ssl-https and achieve the so called data encryption and server identity verification.
Everything is clear regarding the data encryption and the prevention of man-in-the-middle attacks
It seems though that I don't completely understand how server identity verification works, so your help will be highly appreciated.
My understanding so far is the following:
When a client connects to a server via https, the server sends a signed by a CA certificate.
This server certificate is a text file containing information regarding the server(name, owner email, public key etc..), plus a digital signature.
This signature is a hash of the content of the server information, encrypted by the CA private key.
The client checks the validity of the signature by producing again -on his own- the hash of server info and decrypting the signature using the CA's public key. If the decrypted signature value is the same with the produced hash, the signature and the certificate subsequently are valid.
Note here that the public-private encryption scheme has a dual nature. A message can be encrypted by the public key and decrypted by the private key. The same message can be encrypted with the private key and decrypted by the public key as well.
What we need to keep in our minds here is that the certificate is a static and non change-able file. Any change on the file will result in a signature mismatch.
I will describe now a way to fool https:
Lets say theres an ebanking site with URL = https://wwww.TheBank.com/ebanking (public IP = 195.134.0.1)
I connect to this URL and my browser gets the server certificate. (theBank.cer)
On the same time I'm the owner of an internet cafe. My internet cafe has its own router, DNS and DCHP servers which I have the knowledge to control. It has a web server as well.
I configure the web server to own ip 195.134.0.1, same as the bank's
I create a route to my router that sends connection requests for 195.134.0.1 to my web server
I configure my DNS to point the above bank URL to 195.134.0.1(my web server)
I place a fraudulent bank site on my web server. For any connections on this site, I instruct the web server to send to the client the certificate I downloaded before.( theBank.cer)
A user comes to my cafe, gets connected to my network and attempts to connect to this bank. My server sends to him the certificate of the bank. His browser will confirm the validity of the certificate, since its indeed the valid one and allow a connection to my fake web site since its URL, IP and hostname are the same with the real one.
So my fraud is successful.
Of corse, this security hole is too obvious to be true. Meaning I haven't understood something in this server identity verification procedure. Can someone please explain to me what I am missing here?
A user comes to my cafe, gets connected to my network and attempts to connect to this bank. My server sends to him the certificate of the bank. His browser will confirm the validity of the certificate, since its indeed the valid one and allow a connection to my fake web site since its URL, IP and hostname are the same with the real one.
Once his browser has confirmed the validity, it knows the bank's real public key, since that's in the certificate. Since your server can't sign anything with the private key corresponding to that public key, nor can you decrypt anything encrypted with that public key, you can't impersonate the bank at all. All you can do is convince the user of the bank's real identity, which you can't impersonate.
I think the key thing you're missing is that the primary purpose of a certificate is for a trusted authority to bind a real-world identity to a public key, such that only the owner of that real world identity knows the corresponding private key.
theBank.cer is a public key.
You cannot use it to decrypt or sign anything.
This signature is a hash of the content of the server information,
encrypted by the CA private key.
The client checks the validity of the signature by producing again -on
his own- the hash of server info and decrypting the signature using
the CA's public key. If the decrypted signature value is the same with
the produced hash, the signature and the certificate subsequently are
valid.
This is more or less what happens with RSA, but not with DSA, which is signature only (no encryption).
In general, you shouldn't talk about "encrypting" with a private key. It doesn't make any sense, since anyone would be able to decrypt with the public key (since it's public). Encryption is about hiding information.
What you can do with a private key is sign and decrypt/decipher. What you can do with a public key is encrypt and verify a signature.
If you mix up when encryption is required and when signatures are required (despite the fact the algorithm are very similar with RSA), you can end up designing systems that don't provide any security.
More generally, the purpose of a public key certificate (X.509 certificate, or even PGP certificate) is to bind an identity (e.g. the server host name) to a public key. (See this question on Security.SE.)
The data my web server will receive will be encrypted by the public
key of the bank
Note that the SSL/TLS traffic is not encrypted using the certificate's private key, but shared keys negotiated during the SSL/TLS handshake.
During the SSL/TLS handshake, that public key is used either to encrypt the pre-master secret or to sign other parameters (depending on the cipher suite), which end up proving to the client that it's communicating with a server that has the private key for this public key.
Since the certificate also binds the server name to the public key, the client then knows it's communicating with the right server.
This is why it's important to verify that (a) the certificate is trusted and (b) it's issued to the server name the client wanted to connect to.

How do web browsers generate key pairs to communicate with https/tls websites?

I've just been doing a bit of wondering and learning, and I wanted to know how this works. I'm pretty sure I understand the concept of public/private key pairs, as i've gotten it to work with ssh, but I was wondering about https sites too. Where does my machine get the key pairs. Does chrome automatically generate a new key pair every session? Is there one hidden on my machine I don't know about?
I could be getting this all wrong, but any help would be great. :)
Browsers only generate key-pairs when the user needs to request a new (typically client) certificate. This is not necessarily related to SSL/TLS, but more of a convenience facility to issue certificates. This has nothing to do with day to day use of HTTPS. (Even if you are using a client-certificate, you only generate the key-pair when that certificate needs to be issued/renewed, typically once a year.)
The keys used for encryption are symmetric keys, negotiated during the handshake, where only the server certificate is required (for authenticated negotiation). You may find more details in this similar question: Can One Public Key be Used to Encrypt and Decrypt Data during the SSL Handshake?
Yes your browser generates only symmetric keys
see http://publib.boulder.ibm.com/infocenter/tivihelp/v2r1/topic/com.ibm.itame2.doc_5.1/ss7aumst18.htm

Certificate - How they get dealed out?

I am interested in web security right now. So I read about PKI and Diffie Hellman authentication forms.
Now I am reading about certificates and I ask me how that works. So I know Browser have some trusted certificates in it, so you trust the pages, the company which the browser is from, trusts already. So when A trusts B and B trusts C --> A trusts C. Standart Web-of-trust thing.
But what I don't get is how for example google did it when they made there applications https. I never had to download a certificate. How works that?
There are a number of commercial bodies whose business is the issuance of digital certificates; these are called "Certificate Authorities" or CAs. The certificates of the top-level keys of these bodies are distributed with the common web browsers, so you will already have them installed.
If you (or Google, or anyone else) want a certificate for your key you send a request (and some money) to one of the well-known CAs. The CA performs some checks to verify that you are who you say you are, and (as long as the checks check out) they make a new certificare by signing your key with their certificate-signing key.
When you send your certificate to some third party they can check your certificate using the CA's certificate stored in their browser, and this allows them to establish that the identity you claim in your certificate is correct.
There are various levels of certificate which carry different levels of guarantee that the identity claimed in the certificate is correct. Basically, the more you pay the more trouble the CA takes in checking your identity and the more insurance they buy!
All browsers store certificates of Certification Authority, who in turn issue certificates for various organizations.

How are ssl certificates verified?

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 :).

Resources