ssl/tls hanshake:: NIST Special Publication 800-52 Revision 1 - ssl

Can someone explain the contradictions in the BOLD text below from the NIST document.
"The handshake protocol is used to optionally exchange X.509 public key certificates (5) to authenticate the server and the client to each other. In order to comply with these guidelines, the server always presents an X.509 public key certificate that complies.........."
(4). In these guidelines, “change cipher spec” refers to a protocol, and “ChangeCipherSpec” refers to the message used in that protocol.
(5). The use of X.509 public key certificates is fundamental to TLS. For a comprehensive explanation of X.509 public key certificates see [Adams99] or [Housley01]. In these guidelines, the terms “certificate” and “public key certificate” are used interchangeably.

Related

TLS- Are there two digital signature in play during handshake

Could you please clarify on the below doubt.
From IBM website,
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10520_.htm
The steps of the digital signature process are as follows:
The sender computes a message digest and then encrypts the digest using the sender's private key, forming the digital signature.
The sender transmits the digital signature with the message.
The receiver decrypts the digital signature using the sender's public key, regenerating the sender's message digest.
The receiver computes a message digest from the message data received and verifies that the two digests are the same.
So there is a digital signature created using the some random message during handshake. Along with it, there is a digital signature value in the personal certificate issued by CA which is called "Digital Signature Value". This Signature value is present in the certificate itself. But there is one more signature value created from random message during handshake also. Why we have 2 times signature here even for one way SSL. Where is my understanding wrong?. Thanks .
encrypts the digest using the sender's private key
Any time you see something about “encrypting with a private key”, expect the explanation to be flawed. There is no such thing as “encrypting with a private key”. What the writer means here is signs the digest using the sender's private key. Calling a signature “encryption” comes from a very limited understanding of cryptography: the two concepts have different properties and they use different algorithms. For example, it is not always possible to “decrypt” a signature and recover the digest that was signed (it's possible with some signature algorithms and impossible with others); all you can do is to verify whether a certain digest has a certain signature.
This being said, yes, there are two signatures.
The signature in the certificate ties the server's public key with the server's name. More precisely, it means that the certificate authority guarantees that the server with a certain name has a certain public key. This guarantees to the client that the certificate is genuine. Anybody can send you a valid certificate for some server name, but the certificate authority only signs a certificate if it knows that the owner of the name is also the owner of the private key associated with the public key in the certificate.
The signature of the digest in the handshake ties the server's public key with this particular handshake. Anybody can sign a handshake with their own private key, but not with somebody else's private key.
From the second signature, the client knows that the handshake was signed by whoever owns a certain private key. From the first signature, the client knows that the owner of a certain private key is the owner of a certain domain name. By putting the two together, the client knows that the handshake was signed by the owner of the domain name.
In fact in a typical handshake there may be more signatures. How does the client decide to trust the CA? After all anybody can sign a certificate with their own private key. In general there is a chain of certificates: the server's certificate is signed by a CA, the CA has its own certificate which is signed by another CA, and so on. This ends with a small set of CA certificates that are hard-coded in the client's operating system or browser. These certificates are known as roots of the chain. They're often called “root CAs”, but note that being a root CA is not a property of a CA, since different systems can have different sets of root CAs.
For more information about TLS, see How does SSL/TLS work?.

How is ECDSA used for key exchange?

When you go to google.com, the certificate under "Subject Public Key Algorithm" shows:
Elliptic Curve Public Key
ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)
Key size: 256 bits
which apparently is ECDSA. I thought ECDSA is used only for signing/signatures and not
for key exchange. What am I missing?
The key doesn't restrict this. Most elliptic-curve keys (leaving out Bernstein) including this one technically can be used for ECDSA signing, ECDH or ECMQV key agreement, or ECIES encryption. The encoding was established by X9.62 because that was the first issued, but the same curves, key values and encoding are used by the other operations. (Many applications also use the point encoding first created by X9.62, but there is some variation there.)
But the cert does. The cert (also) has the KeyUsage extension set to digitalSignature (and the ExtendedKeyUsage extension set to id-kp-serverAuth). This means when used in TLS it can only be used for ECDSA signing to authenticate the server.
TLS/SSL often uses sign-only certs. Most TLS connections nowadays use 'ephemeral' keys (not in a certificate) for key agreement combined with signing by a cert's key (or more exactly by the privatekey matching a publickey cert) for authentication of the server, and optionally but rarely authentication of the client. This provides (Perfect) Forward Secrecy which means that even if a server privatekey is later compromised, recordings of previous sessions cannot be decrypted so their content remains safe (at least from this attack; SSL/TLS only covers transport and never protects against compromise at either endpoint, during or after the session). In the early days of SSL people often didn't bother with PFS, but after Snowden made lots of people aware of mass surveillance programs -- especially non-techie people like managers and bosses and users and customers -- these options became much more widely required or recommended, and used.
For TLS1.0-1.2 (and SSL3, but you should no longer use that because it is broken) key agreement and signing (server authentication) are linked in the ciphersuite: all ciphersuites that use an ECDSA cert for server auth use ECDHE key agreement, and all ciphersuites that use (integer) DSA* cert for server auth use (integer) DHE key agreement; the E in DHE and last E in ECDHE are for ephemeral. Since RSA supports both signing and encryption, an RSA cert key can be used for key transport (encryption) but this is no longer recommended, or it can be used to sign either kind of ephemeral key agreement. (* For hysterical raisins SSL/TLS standards use DSS to mean DSA.) For TLS 1.3 these algorithms are now selected separately, but use of some ephemeral key agreement is practically required on the public net, and use of some signing cert is required nearly always, so they will probably be used in the same combinations as now except RSA-only key encryption is no longer allowed.
See:
https://security.stackexchange.com/questions/20803/how-does-ssl-work (the Great Ursine Epic)
https://security.stackexchange.com/questions/3638/security-of-pki-certificates-certificate-authorities-forward-secrecy
https://security.stackexchange.com/questions/8343/what-key-exchange-mechanism-should-be-used-in-tls
https://security.stackexchange.com/questions/35471/is-there-any-particular-reason-to-use-diffie-hellman-over-rsa-for-key-exchange

How do we know that an SSL signature belongs to a specific certificate?

I am reading the following article about HTTPS:
http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html
I do understand how we can verify that a signature was truly created by VeriSign.
But how can we know that VeriSign created this signature for this specific domain that we are connected to (or actually for this certificate)?
Since I can see the certificate, including the signature, what stops me from creating my own certificate, replacing the signature with the one I saw on the Amazon.com certificate, and pretending to have a certificate signed by VeriSign?
Since I can see the certificate, including the signature, what stops me from creating my own certificate, replacing the signature with the one I saw on the Amazon.com certificate, and pretending to have a certificate signed by VeriSign?
A certificate has a subject, public key, issuer and signature (among other fields). For example, a subject might be example.com (a DNS name) or joe#example.com (and email address), and the issuer might be Startcom. The issuer's signature binds the subject's public key to the subject. That's all a certificate does: it binds a public key to an entity through an authority's signature. The authority is often called "trusted" or "trusted third party".
So the person who is validating the certificate you are trying to forge will extract the issuer, get the issuer's public key (that's in a different certificate), and then use the issuer's public key to verify your certificate data. Since you forged the signature (i.e., used a different public key than that of the issuer), the signature verification will fail.
Because the public key with which you can verify the signature is part of the certificate and also part of the signature. So you can't change any of those things without breaking the signature.
#gilden But I do not try to create a new signature. I use (almost) exactly the same certificate amazon sent me when I tried to https-contact its website (so same signature and same public key as on amazon's cert). The only thing I change on that cert is the name field (i.e. the name of the website/computer who was given the authority by the signer to use this cert to authenticate itself). So I'm going to change this field from "amazon.com" to "rapt.com". Now I can use this cert to convince people rapt.com is a trusted website. What in the SSL algorithm is going to make me fail in my scheme?
Then the browser/client will use the amazon.com public key to communicate with your server, for which you do not have the corresponding private key. Hence you will not be able to decrypt the pre_master_secret from the client certificate message, and the ssl/tls handshake will fail.

OpenSSL and s_client - why is a private key required from the client?

I need to setup a 2 way SSL communication channel between a .NET/WCF application and a third party web server. Right now I am trying get a successful handshake with the host in order to validate that all the elements are setup correctly (client certificate, server certificate authority, network communication...). I'm using the openSSL command line tool to try and validate this, using the s_client command.
Here is what is stopping me, and what I don't understand:
whatever I do, openSSL is expecting to find a private key for the
client certificate
the client certificate was given to me by the third party, but it
does not contain any private key
if I just generate my own private key file using openSSL, I'm getting
a key values mismatch error
Keep in mind that I have just started getting my hands into SSL so I have a very basic understanding of the whole protocol. From what I've been reading, it seems that both server and client need their private key in a 2 way SSL setting. However, I can't figure out how to get a working private key on my client (working with the client certificate that was given to me).
I would very much appreciate if somebody could shed some light on client certificate private keys, as this is giving me a major headache.
Certificates on their own are only public pieces of information. What links a public key certificate to the name it contains is the fact that whoever has legitimate control over that name (e.g. your name or your server's name) also has the private key for it.
Certificates are used to prove the identity of the remote party by challenging the remote party to perform an operation that can only be done with the corresponding private key: signing something (which can be verified with the public key) or deciphering something that was encrypted with the public key. (Both can happen in the SSL/TLS handshake, depending on the cipher suite.)
During the SSL/TLS handshake, the server sends its certificate (in clear) and proves to the client that it has the corresponding private key using an authenticated key exchange.
In your case, you also want to use client-certificate authentication. It's not enough to send the client certificate during the handshake: the client must also prove it has the private key. Otherwise, anyone who receives that certificate could clone it. The point of using certificates is to prevent any cloning, in such a way that you never have to show your own secret (the private key).
More specifically, the client has to sign the handshake messages in the Certificate Verify message of the TLS handshake so that the server can verify it against the public key sent in the client certificate. Without this step, no client-certificate authentication would be taking place.
the client certificate was given to me by the third party, but it does
not contain any private key
Giving you your certificate without its private key seems a bit pointless, unless you're expected to have generated a certificate request on your side beforehand (in which case you would have the private key).
Indeed, rather than being given a certificate and its private key, it's better practice for you to generate your key-pair, create a certificate request (CSR), and have your CA issue a certificate from that CSR (but without them ever knowing your private key). In this case, you would be expected to have kept your private key, and you would be able to use it with the cert you would have received.
This is an interesting question. I was puzzled by TLS related errors while configuring LDAPS, my learnings here.
The names, "public key" and "private key" sound like it's an one-way operations, but it works both ways, anything encrypted by one key and be decrypted by another key - just that one key is made public
Info = openly available data, with unknown integrity - it could be tampered by 3rd party
Signature = Info encrypted by a private key, accompanies Info
Verifying signature = use public key to decrypt the signature and get Info back thus proving "whoever created the signature knows the private key", or, the Info is untouched after it's signed
That is, unless the private key is stolen
Certificate = Info + Signature + public key + private key
Info = the meat
Signature = to verify integrity of Info
public key = to verify other certificates, see Certificate Chain
private key = not included in certificate itself but should be kept by certificate owner, could be used to sign other certificates
Certificate Authority (CA) = Anyone who holds a public / private key pair and creates certificates
CA identity is indicated in Info on a certificate
Certificate Chain = Use public key on mother-certificate to verify the signature on a child-certificate, to ensure child-certificate was created and signed by mother CA
And mother created and signed by grandma, so forth
Root CA = Root CA is the CA you trust unconditionally
Because their certificates (Root Certificates) are pre-loaded in your browser or OS as a source of trust
Also because their certificates are self-signed, its Signature is created using its own private key, verified by its own public key
This could be confusing, but think it as the origin of certificate-based encryption - only when people found out that relying on a few Root CA's to create and sign countless certificates are insecure (private keys might get stolen) and impossible (rapidly increasing demands of certificates), they came up with the idea of certificate chains
Root CA's only create and sign certificates for some Intermediate CA's so private keys are not used too often and is safer
Intermediate CA's can create and sign millions of certificates and get their certificate revoked when a private key is known to be leaked
This is the reason you don't often see the Root Key Ceremony, which signifies the importance of the private key for a Root Certificate: the less the private key is used, the less it could be exposed
Self-Signed Root Certificate = virtually the same as a Root Certificate - just no one but the creator would trust
TLS Handshake = server sends certificate, client validate is against the certificate chain, when verified, exchange a "password" securely
The "password" is then used to encrypt actual data transfer using symmetric encryption
Asymmetric encryption is not used for actual data due to its need for intense computation powers
Client Certificate Authentication = in addition to previous process which authenticates the server, the server demands a valid certificate to be provided by the client, also a signature of previous handshake messages
The signature is created using the private key of the certificate and can be verified by the public key on the certificate
This proves the ownership of the certificate
This is used usually for restricting access to known individual clients
Using certificates means no man-in-the-middle or replay attack could happen
This is often seen in finance or IoT
This is also utilized by LDAPS, which caused mystic error messages when I had a valid certificate in my local keystore but it was not accompanied by its private key
...So, in terms of openssl, when you use -cert you indicate Client Certificate Authentication, with which you will need -key to specify the corresponding private key.
However, for many Web scenarios, even if the certificate for a server is signed by a homemade CA, one only need to add the homemade CA to truststore or keychain then server certificate can be validated. This is done by using -CAfile.
Bottom-line.. If you're sending client certificates, then you would need the client certificates' private key to encrypt the pre-master secret

SSL and public key security

I'm consuming a web service from an Android device using HTTP(s) with SSL. A self-signed (untrusted) certificate is used for client authentication.
I have a general understanding of how public/private keys are used for SSL. From my understanding I can clearly see how a certificate can be used to set up a secure connection and transmit data securely. However I do not understand how they are used for client authentication since the certificate contains the public key and is not kept a secret.
I have a few questions:
Where can I read about how SSL and certificates can be used for client authentication?
Even if the certificate was not made public...by visiting the HTTPS URL in a browser I can view and save the certificate. I can then package up the certificate in a key store and use it from an application.
In this post Jeremy Huiskamp writes
client auth will automatically be performed when the server requests
it
...so client authentication as well as encryption of data can be performed with certificates?
Edited to answer the first part of my question: The client keystore should contain not only the server's public key but also the client's private key. The server must then be able to decrypt using the client's public key? Does this mean the keystore should have two certificates?
First, a quick point about the terminology in public key cryptography:
you sign and decrypt/decipher using a private key,
you verify (a signature) and encrypt/encipher using a public key.
(You don't really "decrypt" using a public key.)
Using SSL/TLS with or without client-authentication, the server presents a certificate (*) for which it has the private key. The server sends its certificate during the SSL/TLS handshake (at the beginning of the connection) and is able to decipher what the client sends using its private key (which it keeps private). The private key and certificates are stored in the server's keystore (or equivalent if it's not implemented in Java).
As part of this, the client uses its truststore, which is a form a keystore that contains trusted certificates, to verify the server certificate. The server certificate could be trusted by being explicitly in the truststore or, in most cases, trusted by linking in to a trusted CA certificate in the truststore (PKI).
The terminology between keystore and truststore in Java can be a bit confusing, you can find more details in this answer.
Regarding your question, the client's truststore doesn't contain the server's public key, but either its certificate or a CA certificate with which it should be verifiable. (It's not just about having the public key, but knowing whose it is, using the other pieces of information in the certificate.)
When you use client-certificate authentication in addition to this, there is a truststore (or equivalent) on the server side and a keystore on the client side too, since the roles are reversed for this purpose.
In the SSL/TLS handshake that uses client-authentication, the server requests a certificate from the client, who sends it (if available).
At the end of this handshake, the client sends a CertificateVerify message, which signs all the messages exchanged so far between the client and the server (so it's something known to both) using the client certificate private key. The server is then able to verify this signature against the public key within the client certificate it has obtained as part of this exchange. This proves to the server that whoever is on the client side has the private key corresponding to the public key in the certificate it has sent.
The next step for the server is to verify whether to trust this certificate, i.e. whether to trust the binding between identity and public key as presented and "sealed" within the certificate.
This is usually done using a PKI, whereby you check the certificate against a known CA, or if your deployment environment is sufficiently small, against a fixed set of trusted certificates. (There can be alternative methods of verification, but their usability will really depend on the circumstances where you want to deploy this system.)
Therefore, for your second question:
The client keystore should contain at least the client's certificate and its private key.
The client truststore should contain the server certificate or a CA certificate with which the server certificate can be verified.
Since both keystore and truststore are a keystore (in the storage format sense, usually a file) used for a different purpose, it's often possible to use the same keystore to serve both the purpose of keystore and truststore.
(*) There are cipher suites that don't rely on certificates, but that's unusual and off topic for this question.
A certificate just binds an identity to a public key. This binding is not secret, so there is no need to keep the certificate secret. If I have John Smith's certificate, I can prove that John Smith owns the secret key corresponding to a particular public key. But since I don't know that secret key, the certificate is of no use to me.
When authentication occurs by certificate, one step is always to have whoever presents the certificate prove they know the secret key corresponding to the public key in the certificate. If you cannot pass that step, the authentication fails.
The server's keystore should have the server's certificate. The client's keystore should have the client's certificate. The client will present its certificate to the server, so the server will learn the client's public key that way. (And vice-versa.)