I am thankful that the security issue has been pushed out of obscurity and into the spotlight during the last few years. Due to well-publicized threats and attacks, almost everyone, from the development staff on the front line to members of the marketing team, understands (or at least pretends to understand) why good security is important.
Unfortunately, though interest in security has grown, a weak understanding persists on how to achieve strong security. Like any maturing industry, you must gain familiarity with a growing body of literature, research, technology, and terminology (How many readers have wondered just what PKI, PKCS, and PKIX are?) before realizing proficiency.
As Java programmers, we have it easier than most. Sun seems to recognize the importance of providing high-quality tools with which to build secure solutions, especially in the enterprise arena. Even so, judging by the questions on Sun's security mailing list (see Resources for a link) little introductory material is available on the topic.
This series, then, is an attempt to shed a little more light on some of the core tools used to build secure applications in Java -- not secure from the byte code perspective that was so popular in the past, but rather secure from a user, application, and network perspective. If you're not clear on the difference between the two, read on and you'll soon see where I'm heading.
I'll begin Part 1 by introducing public-key cryptography, and later explain how to add value with certificates.
You can read the whole series on certificates:
- Part 1: Certificates add value to public-key cryptography
- Part 2: Learn to use the X.509 certificates
- Part 3: Use the Java CRL and X509CRL classes
- Part 4: Authenticate clients and servers, and verify certificate chains
Much of the mechanism underlying modern application and network security builds upon a type of cryptography known as public-key cryptography. You can understand the importance of public-key cryptography to security without understanding the technical details, so let's take a brief cruise through the neighborhood.
Public-key cryptography differs from traditional symmetric, or shared-key cryptography, in its use of two related, but slightly different, keys. One key, the private key, is kept secret by the owner of the key. The other key, known as the public key, may be distributed far and wide by its owner. The keys in the key pair are complementary. Only the private key can decrypt information encrypted with the public key, and vice versa. And only the public key verifies information signed with the private key, and vice versa.
There are several public-key algorithms in use today. The most popular is known as RSA (because it was invented by Rivest, Shamir, and Adleman), which was the subject of a patent that expired in September 1999.
Whatever the specific algorithm used, public-key cryptography avoids the complicated problem of key exchange -- the process by which communicating parties each exchange or otherwise obtain the keys necessary to secure a conversation between them -- and enables a number of desirable applications, including digital signatures.
Key exchange illustrates one of the problems with symmetric-key cryptography that public-key cryptography so elegantly solves. It also introduces the inherent need in public-key cryptography that certificates solve, verifying the authenticity of an entity's purported public key.
Let's take a look.
For any cryptographic process to work, the entities that are intent on using the process must hold the necessary cryptography keys. In the case of shared-key cryptography, both entities must hold the same key. Since the shared key must be kept absolutely secret for the process to be secure, the act of key exchange becomes critical to the security of the process as a whole. You can't just mail the key to your buddy. If any flaws in the key exchange process crop up, the security of the entire application weakens.
Public-key cryptography nicely avoids the key-exchange issue. In public-key cryptography, owners keep their private-keys private and never exchange them. On the other hand, owners can publish public keys anywhere they'd like. As long as you keep your private-key private, and a potential correspondent can obtain your public key, the communication between the two of you remains secure.
Therein lies the problem with public-key cryptography. Consider two entities that have never previously communicated. How can you be sure that the public key that one entity is using to communicate with the other entity is, in fact, that entity's public key? What if the public key, in fact, belongs to a malicious third party performing a man-in-the-middle attack?
Keys are, after all, nothing more than strings of bits. Even if they are tagged with metadata, how can you be sure that no one has tainted the metadata? The solution involves the introduction of an item called a certificate and a trusted third-party known as a certificate authority.
An introduction to certificates
Certificates come in many shapes and sizes, but they all play the same role. At the barest minimum, a certificate is a document that contains information identifying an entity (in the case of X.509 certificates, using that entity's X.500 distinguished name (DN)) and the entity's public key. Another entity digitally signs and therefore certifies both pieces of information.
If you believe that the signing entity is honest and that its private key hasn't been compromised, then you can safely assume that the signing entity believes that the public key indeed belongs to the named entity. Depending on how much you trust the signing entity, that may be all that's required to conduct business.
Of course, to validate the signature of the signing entity, you need the signing entity's public key. Often, that public key is stored in a self-signed certificate -- a certificate digitally signed by the same entity whose public key is contained within. That certificate, to be effective, must be generally distributed (as part of a software package, for example) and easily verified (via a published SHA1 or MD5 hash, for example).
The simplest practical arrangement consists of a chain of two certificates. One certificate contains the public key of the entity with which you wish to communicate. The second certificate, or root certificate, contains the public key of the entity that certified the first certificate. That arrangement is illustrated in Figure 1 below.
As I previously mentioned, for that system to be effective, the root certificate must be generally available and its validity easily verified. Furthermore, all parties planning on taking part in the secure interaction must trust the issuer. In light of that trust, and as an indication of their ability and willingness to create signed certificates for other entities, the root certificate's creator is called a certificate authority (CA).
In practice, transmitting the entire certificate chain between entities is often unnecessary. Many applications (popular Web browsers and Web servers, for example) are preconfigured with a set of acceptable root certificates from well-known CAs. As such, the entities represented by those applications only need to send the certificate containing their public key, as illustrated in Figure 2 above.
The certificate chain could also contain intermediate certificates between the root certificate and the ultimate certificate containing the public key of interest. Figure 3 illustrates the arrangement. In that case, each certificate in the chain may be validated by the next in the chain until the root certificate is reached. Typically, you only encounter certificate chains of that length in situations involving CA mutual authentication.
More on certificates
As I mentioned earlier, certificates come in multiple formats. Popular types include X.509 certificates, PGP (Pretty Good Privacy) certificates, and SDSI (Simple Distributed Security Infrastructure) certificates. The PGP certificate format was the first to achieve widespread usage. Java supports the X.509 format, an international standard created by the ITU (International Telecommunication Union).
Beyond the certificate's owner name and public key and the certifying entity's name and signature, X.509 certificates include additional information that makes them more useful, including the certificate's serial number (used for certificate revocation), a validity period (used to limit a certificate's lifetime), and its signature algorithm identifier.
Trust limits the scalability of public-key cryptography. The difficulties associated with managing public keys and the dangers associated with using an invalid public key mandate the usage of certificates. Certificates, along with a network of trusted third parties known as certificates authorities (CAs), allow public keys to scale to meet the needs to enterprise and interenterprise usage.
Next month, I'll discuss certificate support in the Java platform. You'll examine the APIs, write some code, and consider the important issue of certificate interoperability with other platforms.
Learn more about this topic
- "Construct Secure Networked Applications with Certificates," Todd Sunsted (JavaWorld)
- Part 1Certificates add value to public-key cryptography (January 12, 2001)
- Part 2Learn to use the X.509 certificates (February 16, 2001)
- Part 3Use the Java CRL and X509CRL classes (March 16, 2001)
- Part 4Authenticate clients and servers, and verify certificate chains (April 13, 2001)
- Sun's security mailing list
- The java.security.cert package
- Information on X.509 certificates
- Have a security question? Check out JavaWorld's Java Security discussion
- Sign up for the JavaWorld This Week free weekly email newsletter and keep up with what's new at JavaWorld
- For a complete listing of all How-To Java columns
- Read more articles on Java Security in the JavaWorld Topical Index