站内搜索: 请输入搜索关键词
当前页面: 图书首页 > Servlets and JavaServer Pages: The J2EE Technology Web Tier

Servlets and JavaServer Pages: The J2EE Technology Web Tier

[ directory ]Programmatic Security in a Servlet/JSP How Secure Is Security?

Secure Encrypted Communication

The preceding discussion talked about using security to perform authentication, authorization, and data integrity. However, there are other things that must be done to provide a fully secure conversation between Alice and Bob. The first is encryption. If Bob wants to send private data to Alicefor example, credit card numbersit had better be encrypted. However, there is no point in encrypting the data if the endpoint Bob is sending the data to is itself not trusted. In other words, before Bob sends private data to Alice, Bob should know that he is talking to Alice; Bob has to authenticate Alice. This is the opposite authentication that was talked about previously where Alice (the server) authenticated Bob (the client). Now, the client has to authenticate the server before sending the data. Modern cryptography allows for both these things to happen.

Cryptography allows data to be encrypted with a key so that it can only be decrypted with a "matching" key. There are two types of key encryption, symmetric key encryption and asymmetric key encryption.

A symmetric key represents a shared secret, and the same key is used to both encrypt and decrypt the data. The problem with symmetric key encryption is "key exchange". How do two parties securely exchange a symmetric key? Alice cannot simply send it to Bob because Mallory can see it.

An asymmetric key is a key that is split into two parts: the private key and the public key. Either can decrypt data encrypted by the otherthat is, data encrypted by the public key only can be decrypted by the private and vice versa. Note that data encrypted by one key can only be decrypted with the other key. The private key is truly private. It is only known by a single entity. The public key is truly public and can be known by everyone.

Encrypting data with the public key is useful, as that data can only be decrypted with the private key. That means that no one can read that data except the private key owner. That is, if Bob encrypts data using Alice's public key, only Alice can decrypt that data.

What about encrypting data using a private key? If Alice encrypts data using her private key, anybody can decrypt it with Alice's public key (the key is public and so is available to anybody). This is also extremely useful as it can be used to prove identity. If Alice sends Bob some plain text, and also encrypts that plaintext with her private key and sends the encrypted data, Bob can take the encrypted data and decrypt it with Alice's public key. He can then compare the decrypted data with the plaintext and compare them. If the comparison is equal, then the plain text must have come from the person whose public key Bob has, so Bob "proves" the data has come from Alice. In this case, Alice is said to have "signed" her data, and typically a hash of the data, rather than the data itself, is signed. A question you should be asking at this point is "How does Bob know that he has Alice's key and not somebody else's?" This is where something called certificates come in, but we will postpone discussion of certificates for now.

So which do we use, symmetric or asymmetric keys? Asymmetric encryption is fine for encrypting/decrypting a hash but is typically an order of magnitude, or slower than a symmetric key when used for encrypting/decrypting bulk data[5]. So the best bet is for two principals to exchange a symmetric key for data encryption, valid for the lifetime of the interaction between the two principals. But how best to exchange this session key securely so that it cannot be seen and so that both parties really know who they are sharing the key with? The answer is using asymmetric keys. Not only do asymmetric keys lend themselves toward generating digital signatures but also secure exchange of symmetric keys.

[5] Using public key private key pairs also has other issues. For example, an attacker will have a copy of the public key; the attacker will also have lots of ciphertext encrypted with the private key. The attacker could also guess some of the plaintext that was encrypted (such as request lines and HTTP headers). The more data an attacker has, the easier it is to break the encryption.

Alice and Bob want to exchange a session key. Alice generates a session key and encrypts it with Bob's public key. She signs the encrypted session key with her private key and sends the signed encrypted session key to Bob. Bob can use Alice's public key to verify the data came from Alice and only Bob can decrypt the session key. Bob now has trust in Alice and the session key. Bob now encrypts the session key with Alice's public key. He signs the encrypted session key with his private key and sends the signed encrypted session key back to Alice. Alice now has trust in Bob and the session key. This assumes, of course, that Alice and Bob have already securely exchanged public keys. Even though public keys can be read and used by anyone, what they cannot do is send public keys to each other on the wire.

If Mallory were to intercept the key exchange, he could just sit in the middle and pretend to be Bob to Alice and Alice to Bob and read all traffic between them. If Alice and Bob knew each other, they could exchange public keys face to face without Mallory being able to get in the middle. If not, they could use a trusted intermediary, Trent (someone they had both securely exchanged keys with in the past). Assume Alice and Bob both trust Trent and have already obtained Trent's public key securely. Also suppose Trent trusts both of them and has already obtained their public keys securely. Trent can put Bob's public key and details in a package called a certificate, sign it, and send it to Alice. She knows it came from Trent and can trust the contents. Likewise, Trent can place Alice's public key in a signed certificate and send it to Bob who knows it came from Trent and has not been tampered with in transit. In fact, Trent could issue Alice and Bob their own certificates, signed by him. This way, for example, Bob could authenticate himself to any other party that also trusted Trent by just sending his certificate (signed by Trent) containing his public key.

Of course, this authentication technique, involving certificate exchange, only works among those parties who trust Trent. Those who have certificates signed by Trudy cannot exchange certificates with those who have certificates signed by Trent, unless, that is, Trudy and Trent both have certificates themselves that are issued and signed by someone they both trust, Todd. This is termed a certificate chain. In this case, for Bob to authenticate to Carol (who trusts Trudy) he must pass her both his certificate (signed by Trent) and Trent's certificate (signed by Todd). In this way Carol can verify that Bob is trusted by Trent who is trusted by Todd and that is OK because Trudy (who Carol trusts) is also trusted by Todd. At the top of the tree there must be some single certificate authority (CA) that everyone trusts and who is able to sign their own certificates.

In the real world there is a standard for certificates called X.509, and there are several CAs who are trusted by everyone and whose public keys are well knownfor example, Verisign. Certificates issued by Verisign are globally recognized, and Verisign's public key gets distributed with commercial client and server software such as browsers and Web servers. A company could act as its own certificate authority to all of its departments, but those certificates would only be usable within the company, not globally.

So where are we? In order for two parties to authenticate each other they exchange certificates and then they can use asymmetric encryption to exchange a session key securely. From that point on, data can be encrypted or signed using the shared session key. This is essentially what SSL does, although it's a little more complex than that. There are two modes that make sense in SSL. First, mutual authentication where the caller and server exchange certificates so they both know who each other is. Second, server authentication where the server sends a certificate to the caller so the caller knows who the server is. SSL uses a four-way handshake, shown in Figure 10-6, that progressively builds up trust between the two parties.

Figure 10-6. Illustration of a Four-Way SSL Handshake

graphics/10fig06.gif


A vastly simplified explanation follows, involving a client running on behalf of Alice and a server running on behalf of Bob.

SSL/TLS is a lot of work! But the work is needed. In cases where it must be ensured, to a best effort, that information is secure and authentic, then you have little choice but to use SSL. The good news is that you do not have to implement the entire SSL protocol before using it with a Web Application. Should your container support SSL, then it is the container vendor's job to implement it. In most popular containers, Tomcat included, SSL support is available. The only thing you need to provide is a certificate from a CA.

Specifying HTTPS

One of the web.xml elements that has yet to be explained is the user-data-constraint element. The user-data-constraint element can be used to specify the level of security a request and response must adhere to. The child element transport-guarantee can be used to set a value of either NONE, INTEGRAL, or CONFIDENTIAL. The NONE value is the default and requires no level of security be enforced. The INTEGRAL value specifies that a container must ensure the integrity of informationthat is, it has not changed during transit but it might have been read by others. The CONFIDENTIAL value requires that information sent in a request and response is both private and unchangedfor example, SSL.

Use of the user-data-constraint element is straightforward. For example, to ensure the protected part of a Web Application is kept completely confidential, the following entry could be used:



...
 <security-constraint>
   <web-resource-collection>
     <web-resource-name>SecuredBookSite</web-resource-name>
     <url-pattern>/tlssecured/*</url-pattern>
     <http-method>GET</http-method>
     <http-method>POST</http-method>

   </web-resource-collection>
   <user-data-constraint>
     <transport-guarantee>CONFIDENTIAL</transport-guarantee>
   </user-data-constraint>
 </security-constraint>
...

Now all resources under the /tlssecured virtual folder of a Web Application are completely private, not just difficult to see. If you try this on your PCfor example, browse to http://127.0.0.1/jspbook/tlssecured/Fooinstead of HTTP the browser would automatically redirect to a secure port/protocol, for instance, https://127.0.0.1/jspbook/tlssecured using port 443. You can try this on your own PC, but there are several things that have to first be done.

Make sure that port is set to 80 (as done in Chapter 1) and that redirectPort is set to 443. These values are the default HTTPS and HTTP ports; the values for a default Tomcat install are 8443 and 8080, respectively. The important thing for now is that the value of redirectPort in the second entry matches the value of the port for the first entry; they are both 443 in the examples shown here.

Once you have uncommented the HTTPS entry, Tomcat is almost ready to listen for HTTPS requests, but to do so, you have to install a security certificate. A certificate is an integral part of HTTPS as will be seen later[6]. Type one of the following to generate a certificate:

[6] If you are using a JDK prior to JDK 1.4, you will need to download and install the Java Secure Sockets Extensions, JSSE. See Sun's Web site at http://java.sun.com/products/jsse/ for more details.

Fill in the values that are asked for by keytool. The values may be fictitious as this is a custom certificate made by you, but they will be appearing later. Make sure that both requested passwords are "changeit" (without the quote marks). Figure 10-7 shows a complete execution of the program.

Figure 10-7. Using Java's Keytool to Create a Certificate

graphics/10fig07.jpg


Once that is done a .keystore file is generated in your home directory with all the information needed by the certificate. Tomcat needs to know about the certificate you just generated. By default Tomcat looks in the home directory of the user that executed it for the .keystore file, which is convenient[7]. Now you can browse to a resource under the /tlssecured virtual directory and SSL will be used. For instance, try browsing to http://127.0.0.1/jspbook/tlssecured/. The URL is redirected to https://127.0.0.1/jspbook/tlssecured/ and you are asked for a user name and password. Assuming you put in the correct information the content is displayed same as before, but the complete request and response are thoroughly encrypted (even if it is just a 404 page). Since you created a custom certificate, do not be surprised if your Web browser complains about the certificate's validity. It is a certificate that no third party will verify because you never registered it with a CA. For instance, Mozilla will complain similar to Figure 10-8, but it is fine because the certificate is only being used for an example.

[7] If Tomcat cannot find the .keystore file, you need to manually set the location of it using the factory elements keyStore attribute. See http://jakarta.apache.org/tomcat/tomcat-5.0-doc/ssl-howto.html for more information.

Figure 10-8. Invalid Certificate in Mozilla

graphics/10fig08.jpg


Typically, in HTTPS only the server is authenticatedthat is, the server does not care who you are, but a secure connection is still needed. As the discussion of the SSL handshake above shows, HTTPS does allow for mutual authentication. In this case where this is needed, the client has to install their certificate in the browser. Additionally, the auth-method element must be set to CLIENT-CERT.

If a request was made over a secure channel, then the Servlet can find out via isSecure(). Additionally, the container associates some of the characteristics of the secure channel with the following request scoped attributes:

The attributes can be mined as needed to know more about the security of the connection. For more information about the X509Certificate object, consult the Java documentation for the object and the rest of the Java 2 Security API.

[ directory ]Programmatic Security in a Servlet/JSP How Secure Is Security?