MIDP Application Security 2: Understanding SSL and TLS

   



Transport Layer Security (TLS) is a protocol that enables authentication and data encryption over insecure networks. It is implemented as a layer between TCP/IP and higher-level network protocols like HTTP, SMTP, and NNTP. The implementation of SSL in web browsers is nearly seamless for users, providing cryptographic authentication and session-based encryption at a minimal cost in ease of use.

This article describes TLS and its close cousin, Secure Sockets Layer (SSL). You'll learn how MIDP (the Mobile Information Device Profile) 1.0 and MIDP 2.0 support TLS and SSL, code some examples, and get an understanding of the security level of TLS and SSL.

Overview of TLS

The TLS protocol is an updated version of the SSLv3 protocol, originally created by Netscape. The two protocols are closely related, although not directly interoperable.

One of the strengths of TLS is that it operates directly on top of TCP/IP sockets, and they behave very much like TCP/IP sockets as far as higher-level protocols are concerned. As a result it's relatively easy to make network applications use an TLS socket instead of a plain vanilla socket. One common example is an application using HTTPS, which is the HTTP protocol running on a TLS or SSL socket.

The TLS protocol begins with a handshake, in which the client and server try to agree on a cipher suite, a group of cryptographic algorithms they will use for authentication and session encryption. Once the client and server have negotiated a cipher suite, they can authenticate each other and generate something called a premaster secret, which is used as the basis of the session key. The session key is used to encrypt and decrypt all data traffic sent between the client and the server. The tricky part is having both the client and server agree on a session key without ever sending it as plaintext over the network. The exact mechanism for this depends on the cipher suite selected.

As a dialogue, one likely TLS handshake looks like this:

Client : Hello, here is a list of cipher suites I can use.

Server : Hello, here is the cipher suite I chose from your
list. And here's an X.509v3 certificate that
contains my public RSA key.

Client : [Scrutinizes the certificate, checks to make sure
it's signed by a known certificate authority.]
Okay, thanks. Here's the premaster secret,
encrypted with your public key. The next thing I
say to you will be encrypted with the session
key.

Client : [Encrypted] I'm done with the handshake.

Server : [Decrypts the premaster secret using private
key, then generates the session key.] The next
thing I send will be encrypted.

Server : [Encrypted] I'm done with the handshake too.

In this case, the client sends a premaster secret encrypted with the server's public key. The server is then authenticated, because only the server's private key can be used to decrypt the premaster secret. Even though the server already sent its certificate to the client, it proves it has the corresponding private key (and thus proves its identity) by correctly decrypting the premaster secret sent by the client. Starting from the same premaster secret, the client and server indpendently generate the same session key.

TLS also supports the use of the Diffie-Hellman (DH) key-exchange protocol. The exchange of messages is a little different from the RSA-based example above, but the end result is that both parties have the same premaster secret and can generate the same session key.

Variations are possible. The server can ask the client for its certificate, for example, although this rarely happens in practice. See the TLS specification for all the details.

Authentication in SSL and TLS

The server authenticates itself by sending its certificate to the client and proving that it possesses the corresponding private key. To verify the certificate, the client must possess the root certificate for the key that was used to sign the server's certificate. How does it get the root certificate? Desktop browsers face exactly the same problem.

The solution is the same as well. Like browsers, devices are shipped with root certificates for widely recognized certificate authorities. When a server presents a certificate, the device checks to see if it has the appropriate root certificate. If so, the device can verify the server certificate.

TLS in MIDP 1.0

The only network connection type mandated by the MIDP 1.0 specification is HTTP. Due to the flexible Generic Connection Framework, however, MIDP implementors are free to support additional connection types, including raw TLS sockets and HTTPS connections. Obtaining an HTTPS connection is just like obtaining an HTTP, except for the URL:

HttpConnection hc = (HttpConnection)
Connector.open("https://www.cert.org/");

If you get a ConnectionNotFoundException for a server you know exists, then chances are good that the underlying implementation doesn't support HTTPS.

This approach is workable, but you have no programmatic way of finding out the identity of the server or which cipher suite is in use. If you have control of the server, you can configure it to use only cipher suites you consider secure enough for your application.

TLS support in MIDP 2.0

A MIDP 2.0 implementation must support HTTPS, where HTTPS means HTTP carried over any of the following protocols:

New APIs in MIDP 2.0 provide MIDlets with information about secure connections. In particular, the MIDP 2.0 specification includes a javax.microedition.io.HttpsConnection interface, an extension of the familiar HttpConnection. This new interface includes a getSecurityInfo() method that returns an instance of another new interface, SecurityInfo.

The SecurityInfo interface provides methods that return information about a secure connection:

public String getProtocolName()
public String getProtocolVersion()
public String getCipherSuite()
public Certificate getServerCertificate()

You can find out the name and version of the actual protocol being used, which will be one of TLS, SSL, or WTLS. The getCipherSuite() method returns the name of the cipher suite, which most likely will be one of the names defined in the TLS specification. For example, my connection from the MIDP 2.0 reference implementation emulator to https://www.cert.org/ returned the following cipher suite name:

TLS_RSA_WITH_RC4_128_SHA

This name indicates that RSA is used for key exchange, an RC4 stream cipher with a 128-bit session key is used for data encryption, and SHA-1 is used as a message digest function.

Finally, SecurityInfo's getServerCertificate() method returns an instance of javax.microedition.pki.Certificate, which represents a cryptographic certificate. The Certificate interface has methods you can use to find out the certificate's subject, its issuer, its type, and other information. You could, for example, retrieve the name on the server certificate as follows:

String url  
                    
                        =
                      
                    
"https://www.cert.org/";
HttpsConnection hc  
                    
                        =
                      
                    
null;
hc  
                    
                        =
                     (HttpsConnection)Connector.
                    
open(url);
SecurityInfo info  
                    
                        =
                     hc.
                    
getSecurityInfo();
Certificate c  
                    
                        =
                     info.
                    
getServerCertificate();
String name  
                    
                        =
                     c.
                    
getIssuer();
                  

Although the MIDP 2.0 APIs provide access to the cipher suite name, it probably won't be practical in code to examine this field and reject weak cipher suites when communicating with unknown servers. It's much more likely that you are writing a MIDlet that is part of a larger, end-to-end application, and therefore can control the allowable cipher suites at the server end. In the MIDlet, therefore, it makes sense to verify that the identity in the certificate and the cipher suite have the values you are expecting. This gives assurance that you are talking to the server you intended. If you are using HTTPS, the hostname you are using must match a field in the server's certificate; otherwise, the connection will fail. There is no such test for SSL socket connections; you would have to check the certificate in your code.

Breaking Session Keys

You've seen how easy it is to use HTTPS connections instead of HTTP connections. It's entirely transparent to the user and nearly transparent to the application developer. But how do you know that the security provided by HTTPS is sufficient?

Your goal is to make the cost of breaking the system greater than the value of the data you're protecting. One of the reasons TLS is such a nice protocol is that it uses a new session key for each conversation. Breaking a single session key gives an attacker access only to the information exchanged in that conversation.

TLS and its predecessor SSLv3 have been used and scrutinized since 1995. The protocol itself has not been compromised significantly and is not the focus of attacks. The security of TLS, then, rests on the cipher suite, particularly the key length used for the symmetric encryption of the application data.

Given the proven strength of the protocol, the best way to attack TLS is a brute-force or key-search attack on a session key. A brute-force attack consists of trying every conceivable decryption key until the plaintext emerges. On average, an attacker needs to try only half of the available keys. Brute force attacks are well suited to distributed systems; the more machines you have trying out keys, the faster it goes.

In the past, U.S. export laws restricted the length of encryption keys used in products shipped outside the United States to 40 bits. The result was that web browsers were distributed with SSL cipher suites limited to 40-bit keys — presumably becuase at the time the law was created (some time before 1996), the U.S. was able to break a 40-bit key in a comfortable length of time, perhaps a few hours or a couple of days. That was at least six years ago, or four generations of Moore's Law. If you're transmitting anything more valuable than the password to your treehouse, you're going to need longer keys.

The de facto standard for TLS cipher suites is 128 bits. Is that long enough for your application? I can't answer that question for you, of course. You have to do some rough calculations to figure out how much it would cost to break a 128-bit key, then determine whether that cost exceeds the value of your application's information.

Summary

MIDP developers now have access to secure network connections, making mobile commerce and banking applications feasible. TLS provides authentication and encryption as a layer between insecure network transport protocools (usually TCP/IP sockets) and higher-level protocols like HTTP, SMTP, and NNTP. The TLS protocol begins with a handshake, in which the client and server agree upon a cipher suite they will use to encrypt the remainder of the session. Although MIDP 1.0 does not require TLS support, MIDP 2.0 does require support for HTTPS, which is HTTP over TLS or a similar secure protocol. MIDP 2.0 also provides API support for HTTPS, giving MIDlets access to information about the secure connection. Be sure to use cipher suites that are sufficiently secure in comparison to the value of the application data. A 128-bit key is commonly used for online commerce.

Resources




Reader Feedback
Excellent   Good   Fair   Poor  

If you have other comments or ideas for future technical tips, please type them here:

Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.


Back To Top