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, ie 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.)

    链接地址: http://www.djcxy.com/p/21760.html

    上一篇: 简单的SSL如何完成服务器

    下一篇: SSL和公钥安全