Terms and Definitions
- Introduction
- Features and Benefits
- JSSE Standard API
- SunJSSE Provider
- What's New
- Related Documentation
- Secure Sockets Layer (SSL) Protocol Overview
- Why Use SSL?
- How SSL Works
- Key Classes
- Relationship Between Classes
- Core Classes and Interfaces
- SocketFactory and ServerSocketFactory Classes
- SSLSocketFactory and SSLServerSocketFactory Classes
- SSLSocket and SSLServerSocket Classes
- Non-blocking I/O with
SSLEngine- SSLSession Interface
- HttpsURLConnection Class
- Support Classes and Interfaces
- SSLContext Class
- TrustManager Interface
- TrustManagerFactory Class
- X509TrustManager Interface
- KeyManager Interface
- KeyManagerFactory Class
- X509KeyManager Interface
- Relationships between TrustManagers and KeyManagers
- Secondary Support Classes and Interfaces
- SSLSessionContext Interface
- SSLSessionBindingListener Interface
- SSLSessionBindingEvent Class
- HandShakeCompletedListener Interface
- HandShakeCompletedEvent Class
- HostnameVerifier Interface
- X509Certificate Class
- Previous (JSSE 1.0.x) Implementation Classes and Interfaces
- Customizing JSSE
- The Installation Directory <java-home>
- Customization
- JCE and Hardware Acceleration/Smartcard Support
- Use of JCE
- Hardware Accelerators
- Configure JSSE to use Smartcards as Keystore and Trust Stores
- Multiple and Dynamic Keystores
- Kerberos Cipher Suites
- Kerberos Requirements
- Peer Identity Information
- Security Manager
Additional Keystore Formats (PKCS12)
- Troubleshooting
- Configuration Problems
- Debugging Utilities
Appendix A: Standard Names
- Code Examples
- Converting an Unsecure Socket to a Secure Socket
- Running the JSSE Sample Code
- Creating a Keystore to Use with JSSE
Data that travels across a network can easily be accessed by someone who is not the intended recipient. When the data includes private information, such as passwords and credit card numbers, steps must be taken to make the data unintelligible to unauthorized parties. It is also important to ensure the data has not been modified, either intentionally or unintentionally, during transport. The Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols were designed to help protect the privacy and integrity of data while it is transferred across a network.The Java Secure Socket Extension (JSSE) enables secure Internet communications. It provides a framework and an implementation for a Java version of the SSL and TLS protocols and includes functionality for data encryption, server authentication, message integrity, and optional client authentication. Using JSSE, developers can provide for the secure passage of data between a client and a server running any application protocol, such as Hypertext Transfer Protocol (HTTP), Telnet, or FTP, over TCP/IP. (For an introduction to SSL, see Secure Sockets Layer (SSL) Protocol Overview.)
By abstracting the complex underlying security algorithms and "handshaking" mechanisms, JSSE minimizes the risk of creating subtle, but dangerous security vulnerabilities. Furthermore, it simplifies application development by serving as a building block which developers can integrate directly into their applications.
JSSE was previously an optional package (standard extension) to the JavaTM 2 SDK, Standard Edition (J2SDK) versions 1.2 and 1.3. As of v1.4, JSSE is now integrated into the J2SDK.
JSSE provides both an application programming interface (API) framework and an implementation of that API. The JSSE API supplements the "core" network and cryptographic services defined in the Java 2 SDK, v1.4 and later
java.securityandjava.netpackages by providing extended networking socket classes, trust managers, key managers, SSLContexts, and a socket factory framework for encapsulating socket creation behavior. (It also provides a limited public key certificate API that is compatible with Java Development Kit (JDK) 1.1-based platforms. However, please note that this limitedjavax.security.certcertificate API is provided only for backward compatibility with JSSE 1.0.x and should not be used. Instead, use the standardjava.security.certcertificate API.) Because the socket APIs were based on a blocking I/O model, in J2SE 5, a non-blockingSSLEngineAPI was introduced to allow implementations to choose their own I/O methods.The JSSE API is capable of supporting SSL versions 2.0 and 3.0 and Transport Layer Security (TLS) 1.0. These security protocols encapsulate a normal bidirectional stream socket and the JSSE API adds transparent support for authentication, encryption, and integrity protection. The JSSE implementation in the J2SDK 1.4 and later implements SSL 3.0 and TLS 1.0. It does not implement SSL 2.0.
As mentioned above, JSSE is a security component of the Java 2 platform, and is based on the same design principles found elsewhere in the Java Cryptography Architecture (JCA) framework. This framework for cryptography-related security components allows them to have implementation independence and, whenever possible, algorithm independence. JSSE uses the same "provider" architecture defined in the JCA.
Other security components in the Java 2 platform include the Java Cryptography Extension (JCE), the Java Authentication and Authorization Service (JAAS), and the Java Security Tools. JSSE encompasses many of the same concepts and algorithms as those in JCE but automatically applies them underneath a simple stream socket API.
The JSSE APIs were designed to allow other SSL/TLS protocol and Public Key Infrastructure (PKI) implementations to be plugged in seamlessly. Developers can also provide alternate logic for determining if remote hosts should be trusted or what authentication key material should be sent to a remote host.
Note: While the JSSE APIs allow the replacement of the underlying implementations (also known as "pluggability"), due to U.S. export restrictions the 1.4.x release did not permit replacement of the SSL/TLS algorithms. However, with the latest U.S. government export regulations, JSSE in J2SE 5 allows any JSSE provider be used--as long as it supports the cipher suites shown in the Provider Pluggability list in the Appendix. TheTrustManagerFactoryandKeyManagerFactoryare still fully pluggable.Features and Benefits
JSSE includes the following important features:
- Implemented in 100% Pure Java
- Can be exported to most countries
- Provides API support for SSL versions 2.0 and 3.0, and an implementation of SSL version 3.0
- Provides API support and an implementation for TLS version 1.0
- Includes classes that can be instantiated to create secure channels (
SSLSocket,SSLServerSocket, andSSLEngine)- Provides support for cipher suite negotiation, which is part of the SSL handshaking used to initiate or verify secure communications
- Provides support for client and server authentication, which is part of the normal SSL handshaking
- Provides support for Hypertext Transfer Protocol (HTTP) encapsulated in the SSL protocol (HTTPS), which allows access to data such as web pages using HTTPS
- Provides server session management APIs to manage memory-resident SSL sessions
- Provides support for several cryptographic algorithms commonly used in cipher suites, including those listed in the following table:
Cryptographic Functionality Available With JSSE
Cryptographic Algorithm *
Cryptographic Process
Key Lengths (Bits)
RSA
Authentication and key exchange
2048 (authentication)
2048 (key exchange)
512 (key exchange)RC4
Bulk encryption
128
128 (40 effective)DES
Bulk encryption
64 (56 effective)
64 (40 effective)Triple DES
Bulk encryption
192 (112 effective)
AES
Bulk encryption
256
128Diffie-Hellman
Key agreement
1024
512DSA
Authentication
1024
* Note: The SunJSSE implementation uses the JavaTM Cryptography Extension (JCE) for all of its cryptographic algorithms.
JSSE Standard API
The JSSE standard API, available in the
javax.net,javax.net.sslandjavax.security.certpackages, covers:
- Secure (SSL) sockets and server sockets.
- A non-blocking engine for producing and consuming streams of SSL/TLS data (SSLEngine).
- Factories for creating sockets, server sockets, SSL sockets, and SSL server sockets. Using socket factories you can encapsulate socket creation and configuration behavior.
- A class representing a secure socket context that acts as a factory for secure socket factories and engines.
- Key and trust manager interfaces (including X.509-specific key and trust managers), and factories that can be used for creating them.
- A class for secure HTTP URL connections (HTTPS).
- A public key certificate API compatible with JDK 1.1-based platforms.
SunJSSEProviderVerions 1.4 and later of the JDK come with a JSSE provider named "
SunJSSE", which comes pre-installed and pre-registered with the JCA. This provider supplies the following cryptographic services:A table of the cipher suites that SunJSSE supports and all of the reserved names can be found in Appendix A.
- RSA support for the signature-related JCA features of the Java 2 platform.
- An implementation of the SSL 3.0 and TLS 1.0 security protocols.
- An implementation of the most common SSL and TLS cipher suites which encompass a combination of authentication, key agreement, encryption and integrity protection.
- An implementation of an X.509-based key manager which chooses appropriate authentication keys from a standard JCA KeyStore.
- An implementation of an X.509-based trust manager which implements rules for certificate chain path validation.
- An implementation of PKCS12 as JCA keystore type "pkcs12". Storing trusted anchors in PKCS12 is not supported. Users should store trust anchors in JKS format and save private keys in PKCS12 format.
What's New
What's New in JSSE in J2SE 5
The following enhancements were made in the JSSE in the Java 2 Platform Standard Edition 5:
- The SunJSSE implementation now uses the Java Cryptography Extension (JCE) for all its cryptographic algorithms. See Customizing the Encryption Algorithm Providers for more information.
SSLEngine(Non-blocking I/O) allows SSL/TLS applications to choose their own I/O and compute models.- Kerberos cipher suites are available if the underlying OS supports it.
- JCE and hardware accelerator/Smartcard support for performance enhancements and securely storing private data.
- Enhancement of the SunJSSE PKCS#12 implementation.
- Enhanced TrustManager support
- Provider pluggability
- Enabled AES_256 cipher suites by default
- HTTP/HTTPS enhancements
- New/Updated Methods and Classes
Enhanced PKCS#12 Implementation
J2SE 1.4.x provided read-only support for PKCS#12 keystores, and a small number of protection algorithms. The enhanced PKCS#12 keystore in J2SE 5 supports reads and writes of PKCS#12 keystores, and provides more protection algorithms (such as those supported by popular browsers). This improves interoperability of PKCS#12 keystores imported/exported by J2SE, browsers, and other security applications.AES_256 Cipher Suites
The SunJSSE provider in 1.4.2 supported a number of AES_256 cipher suites (RFC 3268) but they were not enabled, even if the unlimited strength JCE jurisdiction policy files were installed. In J2SE 5, AES_256 cipher suites are enabled automatically if the unlimited strength JCE jurisdiction policy files are installed. See the JCE Reference Guide for more information on JCE jurisdiction policy files.
HTTP/HTTPS Enhancements
In J2SE 5, a number of networking enhancements were made that affected HTTPS. Here is a summary of them.For details about these enhancements, see the J2SE 5 Release Notes.
- Connect and read timeouts. In J2SE 1.4.x, the connect and read timeouts for protocol handlers could be set only by using some implementation-specific properties. In J2SE 5, methods were added to URLConnection to allow timeouts to be set.
- Dynamic proxy server configuration and selection. Prior to J2SE 5, proxy server configuration was static, global and configured via system properties. J2SE 5 introduced new classes to allow proxies to be configured dynamically and on a per-URI basis.
- Pluggable cookie support. Prior to J2SE 5, applications managed cookies by reading and setting HTTP headers. 1.5.0 introduced a new class to enable applications to install their own cookie handler that can retrieve cookies from a cookie cache for an HTTP request, and can save cookies from an HTTP response into a cookie cache.
- Pluggable caching support. Some classes were introduced in J2SE 5 to allow applications to install a handler that can cache URL responses.
New/Updated Methods and Classes in J2SE 5
SSLEngineandSSLEngineResultwere added to support non-blocking I/O.SSLContextandSSLContextSpiwere updated to generateSSLEngines.A set of new methods were introduced to
HandshakeCompletedEvent, HttpsURLConnection,andSSLSessionwhich allow retrieval of Principals used by a session. (For example:X500Principalfor X509 based ciphersuites,KerberosPrincipalfor Kerberos suites, etc.) If an attempt is made to obtain the certificate chain for a session which does use certificates (Kerberos cipher suites), aSSLPeerUnverifiedExceptionwill occur.New constructors were added to
SSLExceptionto support exception chaining.A new method was added to
SSLSessionto determine whether a session is valid and available for resuming/joining. Another method was added to determine the port infomation of the session, if available. Lastly, two methods were added to determine the largest buffer sizes necessary when usingSSLEngine.A new abstract class
X509ExtendedKeyManagerwas added to provide forSSLEngineextensions of theX509KeyManagerinterface.SSLContexts require initialization with anX509ExtendedKeyManagerbefore usingSSLEngines.Two
ManagerFactoryParametersfactory classes were added.CertPathTrustManagerParametersallows passing of validation settings toCertPath-basedTrustManagers.KeyStoreBuilderParameterswas added to support dynamic key stores. (See theKeyStore.Builderclass or the Multiple and Dynamic Keystores section for more information on dynamicKeyStores.)The rest of this section highlights the differences between the JSSE in releases 1.4.2 and 1.4 of the Java 2 Platform and earlier releases.
What's New in JSSE in the J2SDK 1.4.2
The following changes were introduced in the JSSE in version 1.4.2 of the Java 2 platform:
- The SunJSSE implementation now supports a number of additional ciphersuites. They include ciphersuites using AES as a symmetric cipher and ephemeral Diffie-Hellman with RSA authentication (DHE_RSA). For more information, see the table of "Supported Cipher Suites" in the section
SunJSSEProvider.
- In addition to the simple X.509 based trustmanager previously available in the SunJSSE provider, it now supports a second, PKIX-compliant trust manager. It is implemented using the default CertPath PKIX implementation. For more information, see the section
TrustManagerFactoryClass.What's New in JSSE in the J2SDK 1.4
Here are the differences between JSSE 1.0.2 and the JSSE in the J2SDK 1.4:
- JSSE Is Now in J2SDK
javax.security.certShould Not Be Used- SunJSSE Provider Can Use JCE Providers for Encryption
- Classes Formerly in
com.sun.net.sslAre Now in javax.net.ssl- New Methods and Interface
- Changed Classes and Methods
- Documentation Improvements
JSSE Is Now in J2SDK
JSSE was previously an optional package (extension) to the JavaTM 2 SDK, Standard Edition (J2SDK), versions 1.2 and 1.3. JSSE has now been integrated into the J2SDK, v1.4. The SunJSSE provider is also included and is pre-registered in the
java.securitysecurity properties file included with the J2SDK, v1.4.
javax.security.certShould Not Be UsedJSSE was developed before the
java.security.certpackage was widely available, so a supplemental certificate package was introduced in earlier versions of JSSE calledjavax.security.cert. JSSE is now bundled into the JDK itself and takes advantage of the more complete certificate API available in thejava.security.certpackage. All new applications should usejava.security.cert. Thejavax.security.certpackage exists only for backward compatibility with previous JSSE releases, and should no longer be used.SunJSSE Provider Can Use JCE Providers for Encryption
The SunJSSE provider can now make use of JCE providers for encryption algorithms. Previously, SunJSSE always made use of internal implementations for encryption algorithms. Now implementations from providers with a higher preference order than SunJSSE are used if available. See Customizing the Encryption Algorithm Providers for more information.
Note: SunJSSE in J2SE 5 Development Kit now uses JCE exclusively for its cryptographic algorithms. SunJSSE no longer contains an internal cryptographic routines.
Classes Formerly in com.sun.net.ssl Are Now in javax.net.ssl
All of the classes and interfaces formerly (in JSSE 1.0.x) in the
com.sun.net.sslpackage have been promoted to thejavax.net.sslpackage. The oldcom.sun.net.sslclasses and interfaces still exist and are unchanged, but are included in the SunJSSE provider only for backward compatibility. What is provided is actually "wrappers" that reference the newjavax.net.sslclasses/interfaces.The implementation now uses
javax.net.ssl.SSLPermissionsrather thancom.sun.net.ssl.SSLPermission, so any policy files that used to mentioncom.sun.net.ssl.SSLPermissionshould now usejavax.net.ssl.SSLPermissionsinstead.New Methods and Interfaces
New methodssetWantClientAuthandgetWantClientAuthwere added toSSLSocketandSSLServerSocket(injavax.net.ssl) to enable optional client authentication.The method
SSLContext.getInstance(protocol)returns socket factories which support at least the specified protocol. New methodssetEnabledProtocolsandgetEnabledProtocolswere added toSSLSocketandSSLServerSocketto further refine which protocols are enabled for use on this connection. Another new methodgetSupportedProtocolswas added toSSLSocketandSSLServerSocket;getSupportedProtocolscan be used to obtain the protocol versions that can be enabled for use on an SSL connection. The new methodgetProtocolwas added toSSLSessionfor retrieving the standard name of the protocol used in the session.
SocketFactoryandServerSocketFactoryhave new methodscreateSocketandcreateServerSocket, respectively, for creating unconnected sockets.New methods
getServerSessionContextandgetClientSessionContextwere added toSSLContext. They allow the developer to obtain the set of SSL client or server sessions available for reuse during handshaking.New methods
setSessionTimeoutandgetSessionTimeoutwere added toSSLSessionContext. They allow the developer to control when sessions timeout and become invalid. New methodssetSessionCacheSizeandgetSessionCacheSizewere also added to control how many sessions should be cached for reuse by future connections.New methods were added to
HttpsURLConnection,SSLSession, andHandshakeCompletedEvent(all injavax.net.ssl) that allow you to get generic Java 2java.security.cert.Certificatecertificates in addition to thejavax.security.cert.X509Certificatecertificates returned by previously-existing methods. The new methods areSSLSession.getPeerCertificates
HandshakeCompletedEvent.getPeerCertificates
HttpsURLConnection.getServerCertificatesA
getLocalCertificatesmethod was added toSSLSession,HandshakeCompletedEvent, andHttpsURLConnection. This method returns the certificate(s) that were sent to the peer during handshaking. This provides a way to determine what certificate chain was actually used to authenticate the local side of a given SSL session.A new interface
ManagerFactoryParameterswas added as a base interface that providers can extend if they needKeyManagerFactoryand/orTrustManagerFactoryinitialization parameters other than the ones that can be passed to the KeyStore-basedinitmethods of those classes. TheKeyManagerFactoryandTrustManagerFactoryclasses each have a newinitmethod that takes aManagerFactoryParametersargument. Users of a particular provider are expected to pass an implementation of the appropriateManagerFactoryParametersas defined by the provider.Changed Classes and Methods
When the
com.sunAPIs were prepared for inclusion in thejavaxnamespace, some API limitations were corrected in thejavaxversion. The oldcom.sun.*APIs found in the previous JSSE optional packages are still the same and have not changed. The changes described in the paragraphs below only apply to the newjavax.*classes of the same name.The
HttpsURLConnectionconstructor has been changed to be protected. This was done for consistency with other similar classes such asURLConnection,JarURLConnection, andHttpURLConnection, all in thejava.netpackage. Another change to theHttpsURLConnectionclass is that the method that returnedjavax.security.certcertificates was removed.Hostname verification has been redone to be more generic. The negotiated
SSLSessionis now passed to the verifier'sverifymethod instead of the hostname contained in the received certificates. TheSSLSessioncan then be queried for the negotiated ciphersuite, the exchanged certificates, and so on.The
X509TrustManager isClientTrustedandisServerTrustedmethods were renamedcheckClientTrustedandcheckServerTrusted, respectively. If the certificate chain is not trusted by thisTrustManager, thecheckClientTrustedandcheckServerTrustedmethods throw an exception rather than return aboolean(like the former methods did). This allows implementations to ascertain the underlying cause for failure of the trust decision. The checks done bycheckClientTrustedandcheckServerTrustedinclude verifying that the certificate is used for an operation that complies with the certificate's key usage extension. To properly perform this check, it is necessary to pass the authentication type to these methods, and so aString authTypeargument has been added.One parameter has been added and one changed for the
X509KeyManager chooseClientAliasandchooseServerAliasmethods. ASocket socketparameter was added to both methods for specifying the socket to be used for the connection. Thekeytypeparameter for thechooseClientAliasmethod was changed from a single String to an array of Strings specifying the key algorithm type name(s), ordered with the most-preferred type first. For example, thechooseClientAliasmethod signature used to beand now it ischooseClientAlias(String keyType, Principal[] issuers)The parameters help decide which certificate(s) to use when connecting to a remote host.chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket)The default key manager factory algorithm name has been changed from
sun.ssl.keymanager.typetossl.KeyManagerFactory.algorithm. Similarly, the default trust manager factory algorithm name has been changed fromsun.ssl.trustmanager.typetossl.TrustManagerFactory.algorithm.Documentation Improvements
This JSSE Reference Guide was updated and expanded.
There were a number of minor clarifications made to the JSSE javadocs, primarily when discussing illegal arguments and implied behavior.
Related Documentation
Java Secure Socket Extension Documentation
- The JSSE home page, with links to JavaOneSM conference slides, the JSSE FAQ, legal issues, etc.:
http://java.sun.com/products/jsse/- Archive of API-related questions and answers posted to Sun's Java Security team through java-security@sun.com:
http://archives.java.sun.com/archives/java-security.htmlNote: The above mailing list is not a subscription list or a support mechanism. It is simply a one-way channel that you can use to send comments to the Java 2 Standard Edition security team.
- JSSE API documentation:
Java 2 Platform Security Documentation
- Java 2 security homepage:
http://java.sun.com/security/- The JavaTM Certification Path API Programmer's Guide:
http://java.sun.com/j2se/1.5.0/docs/guide/security/certpath/CertPathProgGuide.html
- Links to more Java 2 platform security documents:
http://java.sun.com/j2se/1.5.0/docs/guide/security/
- Tutorial for Java 2 platform security:
http://java.sun.com/docs/books/tutorial/security1.2/- Book on Java 2 platform security:
Inside Java 2 Platform Security: Architecture, API Design, and Implementation by Li Gong. Addison Wesley Longman, Inc., 1999. ISBN: 0201310007. http://java.sun.com/docs/books/security/index.htmlExport Issues Related to Cryptography
For information on U.S. encryption policies, refer to these Web sites:
- U.S. Department of Commerce:
http://www.commerce.gov- Export Policy Resource Page:
http://www.crypto.com/- Computer Systems Public Policy:
http://www.cspp.org/- Federal Information Processing Standards Publications (FIPS PUBS) homepage, which has links to the Data Encryption Standard (DES):
http://www.itl.nist.gov/fipspubs/- Revised U.S. Encryption Export Control Regulations:
http://www.epic.org/crypto/export_controls/regs_1_00.htmlCryptography Documentation
Online resources:
- Dr. Rivest's Cryptography and Security page:
http://theory.lcs.mit.edu/~rivest/crypto-security.htmlBooks:
- Applied Cryptography, Second Edition by Bruce Schneier. John Wiley and Sons, Inc., 1996.
- Cryptography Theory and Practice by Doug Stinson. CRC Press, Inc., 1995.
- Cryptography & Network Security: Principles & Practice by William Stallings. Prentice Hall, 1998.
Secure Sockets Layer Documentation
Online resources:
- Documentation from Netscape about SSL:
http://developer.netscape.com/docs/manuals/security.html#SSL- Introduction to SSL from Sun™ ONE Software:
http://docs.sun.com/source/816-6156-10/contents.htm- The SSL Protocol version 3.0 Internet Draft:
http://wp.netscape.com/eng/ssl3/ssl-toc.html- The TLS Protocol version 1.0 RFC:
http://www.ietf.org/rfc/rfc2246.txt- "HTTP Over TLS" Information RFC:
http://www.ietf.org/rfc/rfc2818.txtBooks:
- SSL and TLS: Designing and Building Secure Systems by Eric Rescorla. Addison Wesley Professional, 2000.
- SSL and TLS Essentials: Securing the Web by Stephen Thomas. John Wiley and Sons, Inc., 2000.
- Java 2 Network Security, Second Edition, by Marco Pistoia, Duane F Reller, Deepak Gupta, Milind Nagnur, and Ashok K Ramani. Prentice Hall, 1999. Copyright 1999 International Business Machines.
There are several terms relating to cryptography that are used within this document. This section defines some of these terms.
Authentication
Authentication is the process of confirming the identity of a party with whom one is communicating.Cipher Suite
A cipher suite is a combination of cryptographic parameters that define the security algorithms and key sizes used for authentication, key agreement, encryption, and integrity protection.Certificate
A certificate is a digitally signed statement vouching for the identity and public key of an entity (person, company, etc.). Certificates can either be self-signed or issued by a Certification Authority (CA). Certification Authorities are entities that are trusted to issue valid certificates for other entities. Well-known CAs include VeriSign, Entrust, and GTE CyberTrust. X509 is a common certificate format, and they can be managed by the JDK's keytool.Cryptographic Hash Function
A cryptographic hash function is similar to a checksum. Data is processed with an algorithm that produces a relatively small string of bits called a hash. A cryptographic hash function has three primary characteristics: it is a one-way function, meaning that it is not possible to produce the original data from the hash; a small change in the original data produces a large change in the resulting hash; and it does not require a cryptographic key.Cryptographic Service Provider
In the JCA, implementations for various cryptographic algorithms are provided by cryptographic service providers, or "providers" for short. Providers are essentially packages that implement one or more engine classes for specific algorithms. An engine class defines a cryptographic service in an abstract fashion without a concrete implementation.Digital Signature
A digital signature is the digital equivalent of a handwritten signature. It is used to ensure that data transmitted over a network was sent by whoever claims to have sent it and that the data has not been modified in transit. For example, an RSA-based digital signature is calculated by first computing a cryptographic hash of the data and then encrypting the hash with the sender's private key.Encryption and Decryption
Encryption is the process of using a complex algorithm to convert an original message, or cleartext, to an encoded message, called ciphertext, that is unintelligible unless it is decrypted. Decryption is the inverse process of producing cleartext from ciphertext. The algorithms used to encrypt and decrypt data typically come in two categories: secret key (symmetric) cryptography and public key (asymmetric) cryptography.Handshake Protocol
The negotiation phase during which the two socket peers agree to use a new or existing session. The handshake protocol is a series of messages exchanged over the record protocol. At the end of the handshake new connection-specific encryption and integrity protection keys are generated based on the key agreement secrets in the session.Key Agreement
Key agreement is a method by which two parties cooperate to establish a common key. Each side generates some data which is exchanged. These two pieces of data are then combined to generate a key. Only those holding the proper private initialization data will be able to obtain the final key. Diffie-Hellman (DH) is the most common example of a key agreement algorithm.Key Exchange
One side generates a symmetric key and encrypts it using the peer's public key (typcially RSA). The data is then transmitted to the peer, who then decrypts the key using its corresponding private key.Key Managers and Trust Managers
Key managers and trust managers use keystores for their key material. A key manager manages a keystore and supplies public keys to others as needed, e.g., for use in authenticating the user to others. A trust manager makes decisions about who to trust based on information in the truststore it manages.
Keystores and Truststores
A keystore is a database of key material. Key material is used for a variety of purposes, including authentication and data integrity. There are various types of keystores available, including "PKCS12" and Sun's "JKS."
Generally speaking, keystore information can be grouped into two different categories: key entries and trusted certificate entries. A key entry consists of an entity's identity and its private key, and can be used for a variety of cryptographic purposes. In contrast, a trusted certificate entry only contains a public key in addition to the entity's identity. Thus, a trusted certificate entry can not be used where a private key is required, such as in a
javax.net.ssl.KeyManager. In the JDK implementation of "JKS", a keystore may contain both key entries and trusted certificate entries.A truststore is a keystore which is used when making decisions about what to trust. If you receive some data from an entity that you already trust, and if you can verify that the entity is the one it claims to be, then you can assume that the data really came from that entity.
An entry should only be added to a truststore if the user makes a decision to trust that entity. By either generating a keypair or by importing a certificate, the user has given trust to that entry, and thus any entry in the keystore is considered a trusted entry.
It may be useful to have two different keystore files: one containing just your key entries, and the other containing your trusted certificate entries, including Certification Authority (CA) certificates. The former contains private information, while the latter does not. Using two different files instead of a single keystore file provides for a cleaner separation of the logical distinction between your own certificates (and corresponding private keys) and others' certificates. You could provide more protection for your private keys if you store them in a keystore with restricted access, while providing the trusted certificates in a more publicly accessible keystore if needed.
Message Authentication Code
A Message Authentication Code (MAC) provides a way to check the integrity of information transmitted over or stored in an unreliable medium, based on a secret key. Typically, MACs are used between two parties that share a secret key in order to validate information transmitted between these parties.A MAC mechanism that is based on cryptographic hash functions is referred to as HMAC. HMAC can be used with any cryptographic hash function, such as Message Digest 5 (MD5) and Secure Hash Algorithm (SHA), in combination with a secret shared key. HMAC is specified in RFC 2104.
Public Key Cryptography
Public key cryptography uses an encryption algorithm in which two keys are produced. One key is made public while the other is kept private. The public key and the private key are cryptographic inverses; what one key encrypts only the other key can decrypt. Public key cryptography is also called asymmetric cryptography.Record Protocol
The record protocol packages all data whether application-level or as part of the handshake process into discrete records of data much like a TCP stream socket converts an application byte stream into network packets. The individual records are then protected by the current encryption and integrity protection keys.Secret Key Cryptography
Secret key cryptography uses an encryption algorithm in which the same key is used both to encrypt and decrypt the data. Secret key cryptography is also called symmetric cryptography.Session
A session is a named collection of state information including authenticated peer identity, cipher suite, and key agreement secrets which are negotiated through a secure socket handshake and which can be shared among multiple secure socket instances.Trust Managers
See Key Managers and Trust Managers.Truststore
See Keystores and Truststores.
Secure Sockets Layer (SSL) is the most widely used protocol for implementing cryptography on the Web. SSL uses a combination of cryptographic processes to provide secure communication over a network. This section provides an introduction to SSL and the cryptographic processes it uses.
SSL provides a secure enhancement to the standard TCP/IP sockets protocol used for Internet communications. As shown in the "TCP/IP Protocol Stack With SSL" figure below, the secure sockets layer is added between the transport layer and the application layer in the standard TCP/IP protocol stack. The application most commonly used with SSL is Hypertext Transfer Protocol (HTTP), the protocol for Internet Web pages. Other applications, such as Net News Transfer Protocol (NNTP), Telnet, Lightweight Directory Access Protocol (LDAP), Interactive Message Access Protocol (IMAP), and File Transfer Protocol (FTP), can be used with SSL as well.
Note: There is currently no standard for secure FTP.
TCP/IP Protocol Stack With SSL
TCP/IP Layer
Protocol
Application Layer
HTTP, NNTP, Telnet, FTP, etc.
Secure Sockets Layer
SSL
Transport Layer
TCP
Internet Layer
IP
SSL was developed by Netscape in 1994, and with input from the Internet community, has evolved to become a standard. It is now under the control of the international standards organization, the Internet Engineering Task Force (IETF). The IETF has renamed SSL to Transport Layer Security (TLS), and released the first specification, version 1.0, in January 1999. TLS 1.0 is a modest upgrade to the most recent version of SSL, version 3.0. The differences between SSL 3.0 and TLS 1.0 are minor.
Why Use SSL?
Transferring sensitive information over a network can be risky due to the following three issues:
- You cannot always be sure that the entity with whom you are communicating is really who you think it is.
- Network data can be intercepted, so it is possible that it can be read by an unauthorized third party, sometimes known as an attacker.
- If an attacker can intercept the data, the attacker may be able to modify the data before sending it on to the receiver.
SSL addresses each of these issues. It addresses the first issue by optionally allowing each of two communicating parties to ensure the identity of the other party in a process called authentication. Once the parties are authenticated, SSL provides an encrypted connection between the two parties for secure message transmission. Encrypting the communication between the two parties provides privacy and therefore addresses the second issue. The encryption algorithms used with SSL include a secure hash function, which is similar to a checksum. This ensures that data is not modified in transit. The secure hash function addresses the third issue of data integrity.
Note, both authentication and encryption are optional, and depend on the the negotiated cipher suites between the two entities.
The most obvious example of when you would use SSL is in an e-commerce transaction. In an e-commerce transaction, it would be foolish to assume that you can guarantee the identity of the server with whom you are communicating. It would be easy enough for someone to create a phony Web site promising great services if only you enter your credit card number. SSL allows you, the client, to authenticate the identity of the server. It also allows the server to authenticate the identity of the client, although in Internet transactions, this is seldom done.
Once the client and the server are comfortable with each other's identity, SSL provides privacy and data integrity through the encryption algorithms it uses. This allows sensitive information, such as credit card numbers, to be transmitted securely over the Internet.
While SSL provides authentication, privacy, and data integrity, it does not provide non-repudiation services. Non-repudiation means that an entity that sends a message cannot later deny that they sent it. When the digital equivalent of a signature is associated with a message, the communication can later be proved. SSL alone does not provide non-repudiation.
How SSL Works
One of the reasons SSL is effective is that it uses several different cryptographic processes. SSL uses public key cryptography to provide authentication, and secret key cryptography and digital signatures to provide for privacy and data integrity. Before you can understand SSL, it is helpful to understand these cryptographic processes.Cryptographic Processes
The primary purpose of cryptography is to make it difficult for an unauthorized third party to access and understand private communication between two parties. It is not always possible to restrict all unauthorized access to data, but private data can be made unintelligible to unauthorized parties through the process of encryption. Encryption uses complex algorithms to convert the original message, or cleartext, to an encoded message, called ciphertext. The algorithms used to encrypt and decrypt data that is transferred over a network typically come in two categories: secret key cryptography and public key cryptography. These forms of cryptography are explained in the following subsections.Both secret key cryptography and public key cryptography depend on the use of an agreed-upon cryptographic key or pair of keys. A key is a string of bits that is used by the cryptographic algorithm or algorithms during the process of encrypting and decrypting the data. A cryptographic key is like a key for a lock: only with the right key can you open the lock.
Safely transmitting a key between two communicating parties is not a trivial matter. A public key certificate allows a party to safely transmit its public key, while ensuring the receiver of the authenticity of the public key. Public key certificates are described in a later section.
In the descriptions of the cryptographic processes that follow, we use the conventions used by the security community: we label the two communicating parties with the names Alice and Bob. We call the unauthorized third party, also known as the attacker, Charlie.
Secret Key Cryptography
With secret key cryptography, both communicating parties, Alice and Bob, use the same key to encrypt and decrypt the messages. Before any encrypted data can be sent over the network, both Alice and Bob must have the key and must agree on the cryptographic algorithm that they will use for encryption and decryption.
One of the major problems with secret key cryptography is the logistical issue of how to get the key from one party to the other without allowing access to an attacker. If Alice and Bob are securing their data with secret key cryptography, and if Charlie gains access to their key, Charlie can understand any secret messages he intercepts between Alice and Bob. Not only can Charlie decrypt Alice's and Bob's messages, but he can also pretend that he is Alice and send encrypted data to Bob. Bob will not know that the message came from Charlie, not Alice.
Once the problem of secret key distribution is solved, secret key cryptography can be a valuable tool. The algorithms provide excellent security and encrypt data relatively quickly. The majority of the sensitive data sent in an SSL session is sent using secret key cryptography.
Secret key cryptography is also called symmetric cryptography because the same key is used to both encrypt and decrypt the data. Well-known secret key cryptographic algorithms include the Data Encryption Standard (DES), triple-strength DES (3DES), Rivest Cipher 2 (RC2), and Rivest Cipher 4 (RC4).
Public Key Cryptography
Public key cryptography solves the logistical problem of key distribution by using both a public key and a private key. The public key can be sent openly through the network while the private key is kept private by one of the communicating parties. The public and the private keys are cryptographic inverses of each other; what one key encrypts, the other key will decrypt.
Let's assume that Bob wants to send a secret message to Alice using public key cryptography. Alice has both a public key and a private key, so she keeps her private key in a safe place and sends her public key to Bob. Bob encrypts the secret message to Alice using Alice's public key. Alice can later decrypt the message with her private key.
If Alice encrypts a message using her private key and sends the encrypted message to Bob, Bob can be sure that the data he receives comes from Alice; if Bob can decrypt the data with Alice's public key, the message must have been encrypted by Alice with her private key, and only Alice has Alice's private key. The problem is that anybody else can read the message as well because Alice's public key is public. While this scenario does not allow for secure data communication, it does provide the basis for digital signatures. A digital signature is one of the components of a public key certificate, and is used in SSL to authenticate a client or a server. Public key certificates and digital signatures are described in later sections.
Public key cryptography is also called asymmetric cryptography because different keys are used to encrypt and decrypt the data. A well known public key cryptographic algorithm often used with SSL is the Rivest Shamir Adleman (RSA) algorithm. Another public key algorithm used with SSL that is designed specifically for secret key exchange is the Diffie-Hellman (DH) algorithm. Public key cryptography requires extensive computations, making it very slow. It is therefore typically used only for encrypting small pieces of data, such as secret keys, rather than for the bulk of encrypted data communications.
A Comparison Between Secret Key and Public Key Cryptography
Both secret key cryptography and public key cryptography have strengths and weaknesses. With secret key cryptography, data can be encrypted and decrypted quickly, but since both communicating parties must share the same secret key information, the logistics of exchanging the key can be a problem. With public key cryptography, key exchange is not a problem since the public key does not need to be kept secret, but the algorithms used to encrypt and decrypt data require extensive computations, and are therefore very slow.
Public Key Certificates
A public key certificate provides a safe way for an entity to pass on its public key to be used in asymmetric cryptography. The public key certificate avoids the following situation: if Charlie creates his own public key and private key, he can claim that he is Alice and send his public key to Bob. Bob will be able to communicate with Charlie, but Bob will think that he is sending his data to Alice.
A public key certificate can be thought of as the digital equivalent of a passport. It is issued by a trusted organization and provides identification for the bearer. A trusted organization that issues public key certificates is known as a certificate authority (CA). The CA can be likened to a notary public. To obtain a certificate from a CA, one must provide proof of identity. Once the CA is confident that the applicant represents the organization it says it represents, the CA signs the certificate attesting to the validity of the information contained within the certificate.
A public key certificate contains several fields, including:
- Issuer - The issuer is the CA that issued the certificate. If a user trusts the CA that issues a certificate, and if the certificate is valid, the user can trust the certificate.
- Period of validity - A certificate has an expiration date, and this date is one piece of information that should be checked when verifying the validity of a certificate.
- Subject - The subject field includes information about the entity that the certificate represents.
- Subject's public key - The primary piece of information that the certificate provides is the subject's public key. All the other fields are provided to ensure the validity of this key.
- Signature - The certificate is digitally signed by the CA that issued the certificate. The signature is created using the CA's private key and ensures the validity of the certificate. Because only the certificate is signed, not the data sent in the SSL transaction, SSL does not provide for non-repudiation.
If Bob only accepts Alice's public key as valid when she sends it in a public key certificate, Bob will not be fooled into sending secret information to Charlie when Charlie masquerades as Alice.
Multiple certificates may be linked in a certificate chain. When a certificate chain is used, the first certificate is always that of the sender. The next is the certificate of the entity that issued the sender's certificate. If there are more certificates in the chain, each is that of the authority that issued the previous certificate. The final certificate in the chain is the certificate for a root CA. A root CA is a public certificate authority that is widely trusted. Information for several root CAs is typically stored in the client's Internet browser. This information includes the CA's public key. Well-known CAs include VeriSign, Entrust, and GTE CyberTrust.
Cryptographic Hash Functions
When sending encrypted data, SSL typically uses a cryptographic hash function to ensure data integrity. The hash function prevents Charlie from tampering with data that Alice sends to Bob.
A cryptographic hash function is similar to a checksum. The main difference is that while a checksum is designed to detect accidental alterations in data, a cryptographic hash function is designed to detect deliberate alterations. When data is processed by a cryptographic hash function, a small string of bits, known as a hash, is generated. The slightest change to the message typically makes a large change in the resulting hash. A cryptographic hash function does not require a cryptographic key. Two hash functions often used with SSL are Message Digest 5 (MD5) and Secure Hash Algorithm (SHA). SHA was proposed by the U.S. National Institute of Science and Technology (NIST).
Message Authentication Code
A message authentication code (MAC) is similar to a cryptographic hash, except that it is based on a secret key. When secret key information is included with the data that is processed by a cryptographic hash function, the resulting hash is known as an HMAC.If Alice wants to be sure that Charlie does not tamper with her message to Bob, she can calculate an HMAC for her message and append the HMAC to her original message. She can then encrypt the message plus the HMAC using a secret key she shares with Bob. When Bob decrypts the message and calculates the HMAC, he will be able to tell if the message was modified in transit. With SSL, an HMAC is used with the transmission of secure data.
Digital Signatures
Once a cryptographic hash is created for a message, the hash is encrypted with the sender's private key. This encrypted hash is called a digital signature.
The SSL Process
Communication using SSL begins with an exchange of information between the client and the server. This exchange of information is called the SSL handshake.
The three main purposes of the SSL handshake are:
- Negotiate the cipher suite
- Authenticate identity (optional)
- Establish information security by agreeing on encryption mechanisms
Negotiating the Cipher Suite
The SSL session begins with a negotiation between the client and the server as to which cipher suite they will use. A cipher suite is a set of cryptographic algorithms and key sizes that a computer can use to encrypt data. The cipher suite includes information about the public key exchange algorithms or key agreement algorithms, and cryptographic hash functions. The client tells the server which cipher suites it has available, and the server chooses the best mutually acceptable cipher suite.
Authenticating the Server
In SSL, the authentication step is optional, but in the example of an e-commerce transaction over the Web, the client will generally want to authenticate the server. Authenticating the server allows the client to be sure that the server represents the entity that the client believes the server represents.
To prove that a server belongs to the organization that it claims to represent, the server presents its public key certificate to the client. If this certificate is valid, the client can be sure of the identity of the server.
The client and server exchange information that allows them to agree on the same secret key. For example, with RSA, the client uses the server's public key, obtained from the public key certificate, to encrypt the secret key information. The client sends the encrypted secret key information to the server. Only the server can decrypt this message since the server's private key is required for this decryption.
Sending the Encrypted Data
Both the client and the server now have access to the same secret key. With each message, they use the cryptographic hash function, chosen in the first step of this process, and shared secret information, to compute an HMAC that they append to the message. They then use the secret key and the secret key algorithm negotiated in the first step of this process to encrypt the secure data and the HMAC. The client and server can now communicate securely using their encrypted and hashed data.
The SSL Protocol
The previous section provides a high-level description of the SSL handshake, which is the exchange of information between the client and the server prior to sending the encrypted message. This section provides more detail.
The "SSL Messages" figure below shows the sequence of messages that are exchanged in the SSL handshake. Messages that are only sent in certain situations are noted as optional. Each of the SSL messages is described in the following figure:
![]()
The SSL messages are sent in the following order:
- Client hello - The client sends the server information including the highest version of SSL it supports and a list of the cipher suites it supports. (TLS 1.0 is indicated as SSL 3.1.) The cipher suite information includes cryptographic algorithms and key sizes.
- Server hello - The server chooses the highest version of SSL and the best cipher suite that both the client and server support and sends this information to the client.
- Certificate - The server sends the client a certificate or a certificate chain. A certificate chain typically begins with the server's public key certificate and ends with the certificate authority's root certificate. This message is optional, but is used whenever server authentication is required.
- Certificate request - If the server needs to authenticate the client, it sends the client a certificate request. In Internet applications, this message is rarely sent.
- Server key exchange - The server sends the client a server key exchange message when the public key information sent in 3) above is not sufficient for key exchange.
- Server hello done - The server tells the client that it is finished with its initial negotiation messages.
- Certificate - If the server requests a certificate from the client in Message 4, the client sends its certificate chain, just as the server did in Message 3.
Note: Only a few Internet server applications ask for a certificate from the client.
- Client key exchange - The client generates information used to create a key to use for symmetric encryption. For RSA, the client then encrypts this key information with the server's public key and sends it to the server.
- Certificate verify - This message is sent when a client presents a certificate as above. Its purpose is to allow the server to complete the process of authenticating the client. When this message is used, the client sends information that it digitally signs using a cryptographic hash function. When the server decrypts this information with the client's public key, the server is able to authenticate the client.
- Change cipher spec - The client sends a message telling the server to change to encrypted mode.
- Finished - The client tells the server that it is ready for secure data communication to begin.
- Change cipher spec - The server sends a message telling the client to change to encrypted mode.
- Finished - The server tells the client that it is ready for secure data communication to begin. This is the end of the SSL handshake.
- Encrypted data - The client and the server communicate using the symmetric encryption algorithm and the cryptographic hash function negotiated in Messages 1 and 2, and using the secret key that the client sent to the server in Message 8.
- Close Messages - At the end of the connection, each side will send a close_notify message to inform the peer that the connection is closed.
If the parameters generated during an SSL session are saved, these parameters can sometimes be re-used for future SSL sessions. Saving SSL session parameters allows encrypted communication to begin much more quickly.
Cipher Suite Choice and Remote Entity Verification
The SSL/TLS protocols define a specific series of steps to ensure a "protected" connection. However, the choice of cipher suite will directly impact the type of security the connection enjoys. For example, if an anonymous cipher suite is selected, the application will have no way to verify the remote peer's identity. If a suite with no encryption is selected, then the privacy of the data can not be protected. Additionally, the SSL/TLS protocols do not specify that the credentials received must match those that peer might be expected to send. If the connection were somehow redirected to a rogue peer, but the rogue's credentials presented were acceptable based on the current trust material, the connection would be considered valid.When using raw
SSLSockets/SSLEnginesyou should always check the peer's credentials before sending any data. TheSSLSocketandSSLEngineclasses do not automatically verify that the hostname in a URL matches the hostname in the peer's credentials. An application could be exploited with URL spoofing if the hostname is not verified.Protocols such as https do require hostname verification. Applications can use
HostnameVerifierto override the default HTTPS hostname rules. SeeHttpsURLConnectionfor more information.
SSL and TLS References
For a list of resources containing more information about SSL, see Secure Sockets Layer Documentation .
Relationship Between Classes
To communicate securely, both sides of the connection must be SSL-enabled. In the JSSE API, the endpoint classes of the connection is the
SSLSocketandSSLEngine. In the diagram below, the major classes used to createSSLSocket/SSLEngines are laid out in a logical ordering.
![]()
An
SSLSocketis created either by anSSLSocketFactoryor by anSSLServerSocketaccepting an in-bound connection. (In turn, anSSLServerSocketis created by anSSLServerSocketFactory.) BothSSLSocketFactoryandSSLServerSocketFactoryobjects are created by anSSLContext. AnSSLEngineis created directly by the SSLContext, and relies on the application to handle all I/O.
IMPORTANT NOTE: When using rawSSLSockets/SSLEnginesyou should always check the peer's credentials before sending any data. TheSSLSocket/SSLEngineclasses do not automatically verify, for example, that the hostname in a URL matches the hostname in the peer's credentials. An application could be exploited with URL spoofing if the hostname is not verified.
There are two ways to obtain and initialize an
SSLContext:
- The simplest is to call the static
getDefaultmethod on either theSSLSocketFactoryorSSLServerSocketFactoryclass. These methods create a defaultSSLContextwith a defaultKeyManager,TrustManager, and a secure random number generator. (A defaultKeyManagerFactoryandTrustManagerFactoryare used to create theKeyManagerandTrustManager, respectively.) The key material used is found in the default keystore/truststore, as determined by system properties described in Customizing the Default Key and Trust Stores, Store Types, and Store Passwords.- The approach that gives the caller the most control over the behavior of the created context is to call the static method
getInstanceon theSSLContextclass, then initialize the context by calling the instance's properinitmethod. One variant of theinitmethod takes three arguments: an array ofKeyManagerobjects, an array ofTrustManagerobjects, and aSecureRandomrandom number generator. TheKeyManagerandTrustManagerobjects are created by either implementing the appropriate interface(s) or using theKeyManagerFactoryandTrustManagerFactoryclasses to generate implementations. TheKeyManagerFactoryandTrustManagerFactorycan then each be initialized with key material contained in theKeyStorepassed as an argument to theTrustManagerFactory/KeyManagerFactoryinitmethod. Finally, thegetTrustManagersmethod (inTrustManagerFactory) andgetKeyManagersmethod (inKeyManagerFactory) can be called to obtain the array of trust or key managers, one for each type of trust or key material.Once an SSL connection is established, an
SSLSessionis created which contains various information, such as identities established, cipher suite used, etc. TheSSLSessionis then used to describe an ongoing relationship and state information between two entities. Each SSL connection involves one session at a time, but that session may be used on many connections between those entities, simultaneously or sequentially.Core Classes and Interfaces
The core JSSE classes are part of the
javax.netandjavax.net.sslpackages.
SocketFactoryandServerSocketFactoryClassesThe abstract
javax.net.SocketFactoryclass is used to create sockets. It must be subclassed by other factories, which create particular subclasses of sockets and thus provide a general framework for the addition of public socket-level functionality. (See, for example,SSLSocketFactory.)The
javax.net.ServerSocketFactoryclass is analogous to theSocketFactoryclass, but is used specifically for creating server sockets.Socket factories are a simple way to capture a variety of policies related to the sockets being constructed, producing such sockets in a way which does not require special configuration of the code which asks for the sockets:
- Due to polymorphism of both factories and sockets, different kinds of sockets can be used by the same application code just by passing different kinds of factories.
- Factories can themselves be customized with parameters used in socket construction. So for example, factories could be customized to return sockets with different networking timeouts or security parameters already configured.
- The sockets returned to the application can be subclasses of
java.net.Socket(orjavax.net.ssl.SSLSocket), so that they can directly expose new APIs for features such as compression, security, record marking, statistics collection, or firewall tunneling.
SSLSocketFactoryandSSLServerSocketFactoryClassesA
javax.net.ssl.SSLSocketFactoryacts as a factory for creating secure sockets. This class is an abstract subclass ofjavax.net.SocketFactory.Secure socket factories encapsulate the details of creating and initially configuring secure sockets. This includes authentication keys, peer certificate validation, enabled cipher suites and the like.
The
javax.net.ssl.SSLServerSocketFactoryclass is analogous to theSSLSocketFactoryclass, but is used specifically for creating server sockets.Obtaining an
SSLSocketFactoryThere are three primary ways of obtaining an
SSLSocketFactory:
- Get the default factory by calling the
SSLSocketFactory.getDefaultstatic method.
- Receive a factory as an API parameter. That is, code which needs to create sockets but which doesn't care about the details of how the sockets are configured can include a method with an
SSLSocketFactoryparameter that can be called by clients to specify whichSSLSocketFactoryto use when creating sockets. (For example, javax.net.ssl.HttpsURLConnection.)
- Construct a new factory with specifically configured behavior.
The default factory is typically configured to support server authentication only so that sockets created by the default factory do not leak any more information about the client than a normal TCP socket would.
Many classes which create and use sockets do not need to know the details of socket creation behavior. Creating sockets through a socket factory passed in as a parameter is a good way of isolating the details of socket configuration, and increases the reusability of classes which create and use sockets.
You can create new socket factory instances either by implementing your own socket factory subclass or by using another class which acts as a factory for socket factories. One example of such a class is
SSLContext, which is provided with the JSSE implementation as a provider-based configuration class.
SSLSocketandSSLServerSocketClassesThe
javax.net.ssl.SSLSocketclass is a subclass of the standard Javajava.net.Socketclass. It supports all of the standard socket methods and adds additional methods specific to secure sockets. Instances of this class encapsulate theSSLContextunder which they were created. There are APIs to control the creation of secure socket sessions for a socket instance but trust and key management are not directly exposed.The
javax.net.ssl.SSLServerSocketclass is analogous to theSSLSocketclass, but is used specifically for creating server sockets.
To prevent peer spoofing, you should always verify the credentials presented to a SSLSocket.
Implementation note: Due to the complexity of the SSL and TLS protocols, it is difficult to predict whether incoming bytes on a connection are handshake or application data, and how that data might affect the current connection state (even causing the process to block). In the Sun JSSE implementation, the
available()method on the object obtained bySSLSocket.getInputStream()returns a count of the number of application data bytes successfully decrypted from the SSL connection but not yet read by the application.Obtaining an
SSLSocketInstances ofSSLSocketcan be obtained in two ways. First, anSSLSocketcan be created by an instance ofSSLSocketFactoryvia one of the severalcreateSocketmethods on that class. The second way to obtainSSLSockets is through theacceptmethod on theSSLServerSocketclass.Non-blocking I/O with
SSLEngineSSL/TLS is becoming increasingly popular. It is being used in a wide variety of applications across a wide range of computing platforms and devices. Along with this popularity comes demands to use it with different I/O and threading models in order to satisfy the applications' performance, scalability, footprint, and other requirements. There are demands to use it with blocking and non-blocking I/O channels, asynchronous I/O, arbitrary input and output streams, and byte buffers. There are demands to use it in highly scalable, performance-critical environments, requiring management of thousands of network connections.Prior to J2SE 5, the JSSE API supported only a single transport abstraction: stream-based sockets via SSLSocket. While this was adequate for many applications, it did not meet the needs of applications that need to use different I/O or threading models. In 1.5.0, a new abstraction was introduced to allow applications to use the SSL/TLS protocols in a transport independent way, and thus freeing applications to choose transport and computing models that best meet their needs. Not only does this new abstraction allow applications to use non-blocking I/O channels and other I/O models, it also accommodates different threading models. This effectively leaves the I/O and threading decisions up to the application. Because of this flexibility, the application must now manage I/O and threading (complex topics in and of themselves), as well as have some understanding of the SSL/TLS protocols. The new abstraction is therefore an advanced API: beginners should continue to use SSLSocket.
Newcomers to the API may wonder "Why not just have an
SSLSocketChannelwhich extendsjava.nio.channels.SocketChannel?" There are two main reasons:By abstracting the I/O and treating data as streams of bytes, these issues are resolved and the new API could be used with any existing or future I/O model. While this solution makes I/O and CPU handling the developers' responsibility, JSSE implementations are prevented from being unusable due to some unconfigurable and/or unchangeable internal detail.
- There were a lot of very difficult questions about what a
SSLSocketChannelshould be, including its class hierarchy and how it should interoperate withSelectors and other types ofSocketChannels. Each proposal brought up more questions than answers. It was noted that any new API abstraction extended to work with SSL/TLS would require the same significant analysis and could result in large and complex APIs.
- Any JSSE implementation of a new API would be free to choose the "best" I/O & compute strategy, but hiding any of these details is inappropriate for those applications needing full control. Any specific implementation would be inappropriate for some application segment.
Users of other Java programming language APIs such as JGSS and SASL will notice similarities in that the application is also responsible for transporting data.
SSLEngineThe core class in this new abstraction is javax.net.ssl.SSLEngine. It encapsulates an SSL/TLS state machine and operates on inbound and outbound byte buffers supplied by the user of the SSLEngine. The following diagram illustrates the flow of data from the application, to the SSLEngine, to the transport mechanism, and back.The application, shown on the left, supplies application (plaintext) data in an application buffer and passes it to the SSLEngine. The SSLEngine processes the data contained in the buffer, or any handshaking data, to produce SSL/TLS encoded data and places it the network buffer supplied by the application. The application is then responsible for using an appropriate transport (shown on the right) to send the contents of the network buffer to its peer. Upon receiving SSL/TLS encoded data from its peer (via the transport), the application places the data into a network buffer and passes it to SSLEngine. The SSLEngine processes the network buffer's contents to produce handshaking data or application data.
In all, SSLEngine can be in one of five states.
These five states are decribed in more detail in the SSLEngine class documentation.
- Creation - ready to be configured.
- Initial handshaking - perform authentication and negotiate communication parameters.
- Application data - ready for application exchange.
- Rehandshaking - renegotiate communications parameters/authentication; handshaking data may be mixed with application data.
- Closure - ready to shut down connection.
Getting Started
To create an SSLEngine, you use the SSLContext.createSSLEngine() methods. You must then configure the engine to act as a client or a server, as well as set other configuration parameters such as which cipher suites to use and whether to require client authentication.Here is an example that creates an SSLEngine. Note that the server name and port number are not used for communicating with the server--all transport is the responsibility of the application. They are hints to the JSSE provider to use for SSL session caching, and for Kerberos-based cipher suite implementations to determine which server credentials should be obtained.
import javax.net.ssl.*; import java.security.*; // Create/initialize the SSLContext with key material char[] passphrase = "passphrase".toCharArray(); // First initialize the key and trust material. KeyStore ksKeys = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("testKeys"), passphrase); KeyStore ksTrust = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("testTrust"), passphrase); // KeyManager's decide which key material to use. KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ksKeys, passphrase); // TrustManager's decide whether to allow connections. TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ksTrust); sslContext = SSLContext.getInstance("TLS"); sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null); // We're ready for the engine. SSLEngine engine = sslContext.createSSLengine(hostname, port); // Use as client engine.setUseClientMode(true);Generating and Processing SSL/TLS data
The two main SSLEngine methods wrap() and unwrap() are responsible for generating and consuming network data respectively. Depending on the state of the SSLEngine, this data might be handshake or application data.Each SSLEngine has several phases during its lifetime. Before application data can be sent/received, the SSL/TLS protocol requires a handshake to establish cryptographic parameters. This handshake requires a series of back-and-forth steps by the SSLEngine. The SSL Process can provide more details about the handshake itself.
During the initial handshaking, wrap() and unwrap() generate and consume handshake data, and the application is responsible for transporting the data. The wrap()/unwrap() sequence is repeated until the handshake is finished. Each SSLEngine operation generates a SSLEngineResult, of which the SSLEngineResult.HandshakeStatus field is used to determine what operation needs to occur next to move the handshake along.
A typical handshake might look like this:
Now that handshaking is complete, further calls to wrap() will attempt to consume application data and packages it for transport. unwrap() attempts the opposite.
clientSSL/TLS messageHSStatuswrap()ClientHelloNEED_UNWRAPunwrap()ServerHello/Cert/ServerHelloDoneNEED_WRAPwrap()ClientKeyExchangeNEED_WRAPwrap()ChangeCipherSpecNEED_WRAPwrap()FinishedNEED_UNWRAPunwrap()ChangeCipherSpecNEED_UNWRAPunwrap()FinishedFINISHEDTo send data to the peer, the application first supplies the data that it wants to send to SSLEngine via SSLEngine.wrap() to obtain the corresponding SSL/TLS encoded data. The application then sends the encoded data to the peer using its chosen transport mechanism. When the application receives the SSL/TLS encoded data from the peer via the transport mechanism, it supplies this data to the SSLEngine via SSLEngine.unwrap() to obtain the plaintext data sent by the peer.
Here is an example of an SSL application that is using a non-blocking SocketChannel to communicate with its peer. (It can be made more robust and scalable by using a Selector with the non-blocking SocketChannel.) The following sample code sends the string "hello" to its peer, by encoding it using the SSLEngine created in the previous example. It uses information from the SSLSession to determine how large to make the byte buffers.
The following code reads data from the same non-blocking SocketChannel and extracts the plaintext data from it by using the SSLEngine created previously. Each iteration of this code may or may not produce any plaintext data, depending on whether handshaking is in progress.// Create a non-blocking socket channel SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(hostname, port)); // Complete connection while (!socketChannel.finishedConnect()) { // do something until connect completed } // Create byte buffers to use for holding application and encoded data SSLSession session = engine.getSession(); ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize()); ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize()); ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize()); ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize()); // Do initial handshake doHandshake(socketChannel, engine, myNetData, peerNetData); myAppData.put("hello".getBytes()); myAppData.flip(); while (myAppData.hasRemaining()) { // Generate SSL/TLS encoded data (handshake or application data) SSLEngineResult res = engine.wrap(myAppData, myNetData); // Process status of call if (res.getStatus() == SSLEngineResult.Status.OK) { myAppData.compact(); // Send SSL/TLS encoded data to peer while(myNetData.hasRemaining()) { int num = socketChannel.write(myNetData); if (num == -1) { // handle closed channel } else if (num == 0) { // no bytes written; try again later } } } // Handle other status: BUFFER_OVERFLOW, CLOSED ... }// Read SSL/TLS encoded data from peer int num = socketChannel.read(peerNetData); if (num == -1) { // Handle closed channel } else if (num == 0) { // No bytes read; try again ... } else { // Process incoming data peerNetData.flip(); res = engine.unwrap(peerNetData, peerAppData); if (res.getStatus() == SSLEngineResult.Status.OK) { peerNetData.compact(); if (peerAppData.hasRemaining()) { // Use peerAppData } } // Handle other status: BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED ... }Status of Operations
To indicate the status of the engine and what action(s) the application should take, the SSLEngine.wrap() and SSLEngine.unwrap() methods return an SSLEngineResult instance, as shown in the previous examples. The SSLEngineResult contains two pieces of status information: the overall status of the engine and the handshaking status.The possible overall statuses are represented by the SSLEngineResult.Status enum. Some examples of this status include OK, which means that there was no error, and BUFFER_UNDERFLOW, which means that the input buffer had insufficient data, indicating that the application needs to obtain more data from the peer (for example, by reading more data from the network).
The possible handshaking statuses are represented by the SSLEngineResult.HandshakeStatus enum. They represent whether handshaking has completed, whether the caller needs to obtain more handshaking data from the peer, send more handshaking data to the peer, and so on.
Having two statuses per result allows the engine to indicate that the application must take two actions: one in response to the handshaking and one representing the overall status of the wrap()/unwrap() method. For example, the engine might, as the result of a single SSLEngine.unwrap() call, return SSLEngineResult.Status.OK to indicate that the input data was processed successfully and SSLEngineResult.HandshakeStatus.NEED_UNWRAP to indicate that the application should obtain more SSL/TLS encoded data from the peer and supply it to SSLEngine.unwrap() again so that handshaking can continue. As you can see, the previous examples were greatly simplified; they would need to be expanded significantly to properly handle all of these statuses.
Blocking Tasks
During handshaking, the SSLEngine might encounter tasks that might block or take a long time. For example, a TrustManager may need to connect to a remote certificate validation service, or a KeyManager might need to prompt a user to determine which certificate to use as part of client authentication. To preserve the non-blocking nature of SSLEngine, when the engine encounters such a task, it will return SSLEngineResult.HandshakeStatus.NEED_TASK. Upon receiving this status, the application should invoke SSLEngine.getDelegatedTask() to get the task, and then, using the threading model appropriate for its requirements, process the task. The application might, for example, obtain thread(s) from a thread pool to process the task(s), which the main thread goes about handling other I/O.Here is an example that executes each task in a newly created thread.
The engine will block futureif (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) { Runnable task; while ((task=engine.getDelegatedTask()) != null) { new Thread(task).start(); } }wrap/unwrapcalls until all of the outstanding tasks are completed.Shutting Down
For an orderly shutdown of an SSL/TLS connection, the SSL/TLS protocols require transmission of close messages. Therefore, when an application is done with the SSL/TLS connection, it should first obtain the close messages from the SSLEngine, then transmit them to the peer using its transport mechanism, and finally shut down the transport mechanism. Here is an example.In addition to an application explicitly closing the SSLEngine, the SSLEngine might be closed by the peer (via receipt of a close message while it is processing handshake data), or by the SSLEngine encountering an error while processing application or handshake data, indicated by throwing an SSLException. In such cases, the application should invoke SSLEngine.wrap() to get the close message and send it to the peer until SSLEngine.isOutboundDone() returns true, as shown in the previous example, or the SSLEngineResult.getStatus() returns CLOSED.// Indicate that application is done with engine engine.closeOutbound(); while (!engine.isOutboundDone()) { // Get close message SSLEngineResult res = engine.wrap(empty, myNetData); // Check res statuses // Send close message to peer while(myNetData().hasRemaining()) { int num = socketChannel.write(myNetData); if (num == -1) { // handle closed channel } else if (num == 0) { // no bytes written; try again later } myNetData().compact(); } } // Close transport socketChannel.close();In addition to orderly shutdowns, there can also be unorderly shutdowns in which the transport link is severed before close messages are exchanged. In the previous examples, the application might get -1 when trying to read or write to the non-blocking SocketChannel. When you get to the end of your input data, you should call engine.closeInbound(), which will verify with the SSLEngine that the remote peer has closed cleanly from the SSL/TLS perspective, and then the application should still try to shutdown cleanly by using the procedure above. Obviously, unlike SSLSocket, the application using SSLEngine must deal with more state transitions, statuses and programming than when using SSLEngine. Please see the NIO-based HTTPS server for more information on writing a
SSLEngine-based application.
SSLSessionInterfaceA
javax.net.ssl.SSLSessionrepresents a security context negotiated between the two peers of anSSLSocket/SSLEngineconnection. Once a session has been arranged, it can be shared by futureSSLSocket/Engines connected between the same two peers. The session contains the cipher suite which will be used for communications over a secure socket as well as a non-authoritative hint as to the network address of the remote peer, and management information such as the time of creation and last use. A session also contains a shared master secret negotiated between the peers that is used to create cryptographic keys for encrypting and guaranteeing the integrity of the communications over anSSLSocket/SSLEngine. The value of this master secret is known only to the underlying secure socket implementation and is not exposed through theSSLSessionAPI.
HttpsURLConnectionClassThe https protocol is similar to http, but https first establishes a secure channel via SSL/TLS sockets and then verifies the identity of the peer before requesting/receiving data.javax.net.ssl.HttpsURLConnectionextends thejava.net.HttpsURLConnectionclass, and adds support for https-specific features. See thejava.net.URL,java.net.URLConnection,java.net.HttpURLConnection, andjavax.net.ssl.HttpURLConnectionclasses for more information about how https URLs are constructed and used.Upon obtaining a
HttpsURLConnection, you can configure a number of http/https parameters before actually initiating the network connection via the methodURLConnection.connect. Of particular interest are:Setting the Assigned
SSLSocketFactoryIn some situations, it is desirable to specify the
SSLSocketFactorythat anHttpsURLConnectioninstance uses. For example, you may wish to tunnel through a proxy type that isn't supported by the default implementation. The newSSLSocketFactorycould return sockets that have already performed all necessary tunneling, thus allowingHttpsURLConnectionto use additional proxies.The
HttpsURLConnectionclass has a defaultSSLSocketFactorywhich is assigned when the class is loaded. (In particular it is the factory returned by the methodSSLSocketFactory.getDefault.) Future instances ofHttpsURLConnectionwill inherit the current defaultSSLSocketFactoryuntil a new defaultSSLSocketFactoryis assigned to the class via the static methodHttpsURLConnection.setDefaultSSLSocketFactory. Once an instance ofHttpsURLConnectionhas been created, the inheritedSSLSocketFactoryon this instance can be overriden with a call to thesetSSLSocketFactorymethod.Note that changing the default static
SSLSocketFactoryhas no effect on existing instances ofHttpsURLConnections, a call to thesetSSLSocketFactorymethod is necessary to change the existing instance.One can obtain the per-instance or per-class
SSLSocketFactoryby making a call to thegetSSLSocketFactory/getDefaultSSLSocketFactorymethods, respectively.Setting the Assigned
HostnameVerifierIf the hostname of the URL does not match the hostname in the credentials received as part of the SSL/TLS handshake, it's possible that URL spoofing has occured. If the implementation cannot determine a hostname match with reasonable certainty, the SSL implementation will perform a callback to the instance's assignedHostnameVerifierfor futher checking. The hostname verifier can perform whatever steps are necessary to make the determination, such as performing alternate hostname pattern matching or perhaps popping up an interactive dialog box. An unsuccessful verification by the hostname verifier will close the connection. (See RFC 2818 for more information regarding hostname verification.)The
setHostnameVerifier/setDefaultHostnameVerifiermethods operate in a similar manner to thesetSSLSocketFactory/setDefaultSSLSocketFactorymethods, in that there areHostnameVerifiersassigned on a per-instance and per-class basis, and the current values can be obtained by a call to thegetHostnameVerifier/getDefaultHostnameVerifiermethods.Support Classes and Interfaces
The classes and interfaces in this section are provided to support the creation and initialization of
SSLContextobjects, which are used to createSSLSocketFactory, SSLServerSocketFactory, andSSLEngineobjects. The support classes and interfaces are part of thejavax.net.sslpackage.Three of the classes described in this section (
SSLContext,KeyManagerFactory, andTrustManagerFactory) are engine classes. An engine class is an API class for specific algorithms (or protocols, in the case ofSSLContext), for which implementations may be provided in one or more Cryptographic Service Provider (provider) packages. For more information on providers and engine classes, see the "Design Principles" and "Concepts" sections of the JavaTM Cryptography Architecture API Specification & Reference.The
SunJSSEprovider that comes standard with JSSE providesSSLContext,KeyManagerFactory, andTrustManagerFactoryimplementations, as well as implementations for engine classes in the standard Java security (java.security) API. The implementations supplied bySunJSSEare:Engine Class Algorithm or Implemented Protocol KeyFactory "RSA" KeyPairGenerator "RSA" KeyStore "PKCS12" Signature "MD2withRSA", "MD5withRSA", "SHA1withRSA" KeyManagerFactory "SunX509", "NewSunX509" TrustManagerFactory "SunPKIX" (aka "X509"/"PKIX"), "SunX509" SSLContext "SSLv3" (aka "SSL"), "TLSv1" (aka "TLS")
SSLContextClass
javax.net.ssl.SSLContextis an engine class for an implementation of a secure socket protocol. An instance of this class acts as a factory for SSL socket factories and SSL engines. AnSSLContextholds all of the state information shared across all objects created under that context. For example, session state is associated with theSSLContextwhen it is negotiated through the handshake protocol by sockets created by socket factories provided by the context. These cached sessions can be reused and shared by other sockets created under the same context.Each instance is configured through its
initmethod with the keys, certificate chains, and trusted root CA certificates that it needs to perform authentication. This configuration is provided in the form of key and trust managers. These managers provide support for the authentication and key agreement aspects of the cipher suites supported by the context.Currently, only X.509-based managers are supported.
Creating an
SSLContextObjectLike other JCA provider-based "engine" classes,SSLContextobjects are created using thegetInstancefactory methods of theSSLContextclass. These static methods each return an instance that implements at least the requested secure socket protocol. The returned instance may implement other protocols too. For example,getInstance("SSLv3")may return a instance which implements"SSLv3"and"TLSv1". ThegetSupportedProtocolsmethod returns a list of supported protocols when anSSLSocket, SSLServerSocketorSSLEngineis created from this context. You can control which protocols are actually enabled for an SSL connection by using the methodsetEnabledProtocols(String[] protocols).Note: An
SSLContextobject is automatically created, initialized, and statically assigned to theSSLSocketFactoryclass when you callSSLSocketFactory.getDefault. Therefore, you don't have to directly create and initialize anSSLContextobject (unless you want to override the default behavior).To create an
SSLContextobject by calling agetInstancefactory method, you must specify the protocol name. You may also specify which provider you want to supply the implementation of the requested protocol:public static SSLContext getInstance(String protocol);
public static SSLContext getInstance(String protocol,
String provider);
public static SSLContext getInstance(String protocol,
Provider provider);If just a protocol name is specified, the system will determine if there is an implementation of the requested protocol available in the environment, and if there is more than one, if there is a preferred one.
If both a protocol name and a provider are specified, the system will determine if there is an implementation of the requested protocol in the provider requested, and throw an exception if there is not.
A protocol is a string (such as "SSL") that describes the secure socket protocol desired. Common protocol names for
SSLContextobjects are defined in Appendix A.Here is an example of obtaining an
SSLContext:SSLContext sc = SSLContext.getInstance("SSL");A newly-created
SSLContextshould be initialized by calling theinitmethod:public void init(KeyManager[] km, TrustManager[] tm,
SecureRandom random);If the
KeyManager[]paramater is null, then an emptyKeyManagerwill be defined for this context. If theTrustManager[]parameter is null, the installed security providers will be searched for the highest-priority implementation of theTrustManagerFactory, from which an appropriateTrustManagerwill be obtained. Likewise, the SecureRandom parameter may be null, in which case a default implementation will be used.If the internal default context is used, (e.g. a
SSLContextis created bySSLSocketFactory.getDefault()orSSLServerSocketFactory.getDefault()), a defaultKeyManagerand aTrustManagerare created. The defaultSecureRandomimplementation is also chosen.
TrustManagerInterfaceThe primary responsibility of theTrustManageris to determine whether the presented authentication credentials should be trusted. If the credentials are not trusted, the connection will be terminated. To authenticate the remote identity of a secure socket peer, you need to initialize anSSLContextobject with one or moreTrustManagers. You need to pass oneTrustManagerfor each authentication mechanism that is supported. If null is passed into theSSLContextinitialization, a trust manager will be created for you. Typically, there is a single trust manager that supports authentication based on X.509 public key certificates (e.g.X509TrustManager). Some secure socket implementations may also support authentication based on shared secret keys, Kerberos, or other mechanisms.
TrustManagers are created either by aTrustManagerFactory, or by providing a concrete implementation of the interface.
TrustManagerFactoryClassThe
javax.net.ssl.TrustManagerFactoryis an engine class for a provider-based service that acts as a factory for one or more types ofTrustManagerobjects. Because it is provider-based, additional factories can be implemented and configured that provide additional or alternate trust managers that provide more sophisticated services or that implement installation-specific authentication policies.Creating a
TrustManagerFactoryYou create an instance of this class in a similar manner toSSLContext, except for passing an algorithm name string instead of a protocol name to thegetInstancemethod:public static TrustManagerFactory
getInstance(String algorithm);
public static TrustManagerFactory
getInstance(String algorithm,
String provider);
public static TrustManagerFactory
getInstance(String algorithm,
Provider provider);A sample algorithm name string is:
"PKIX"A sample call is the following:
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("PKIX", "SunJSSE");The above call will create an instance of the
SunJSSEprovider's PKIX trust manager factory. This factory can then be used to create trust managers which provide X.509 PKIX-based certification path validity checking.When initializing a
SSLContext, you can use trust managers created from a trust manager factory, or you can write your own trust manager, perhaps using theCertPathAPI. (See the JavaTM Certification Path API Programmer's Guide for details.) You don't need to use a trust manager factory at all if you implement a trust manager using theX509TrustManagerinterface.A newly-created factory should be initialized by calling one of the
initmethods:public void init(KeyStore ks);
public void init(ManagerFactoryParameters spec);You should call whichever
initmethod is appropriate for theTrustManagerFactoryyou are using. (Ask the provider vendor.)For many factories, such as the "SunX509"
TrustManagerFactoryfrom theSunJSSEprovider, theKeyStoreis the only information required in order to initialize theTrustManagerFactoryand thus the firstinitmethod is the appropriate one to call. TheTrustManagerFactorywill query theKeyStorefor information on which remote certificates should be trusted during authorization checks.In some cases, initialization parameters other than a
KeyStoremay be needed by a provider. Users of that particular provider are expected to pass an implementation of the appropriateManagerFactoryParametersas defined by the provider. The provider can then call the specified methods in theManagerFactoryParametersimplementation to obtain the needed information.For example, suppose the
TrustManagerFactoryprovider requires initialization parameters B, R, and S from any application that wishes to use that provider. Like all providers that require initialization parameters other than a KeyStore, the provider will require that the application provide an instance of a class that implements a particularManagerFactoryParameterssub-interface. In our example, suppose the provider requires that the calling application implement and create an instance ofMyTrustManagerFactoryParamsand pass it to the secondinit. Here is whatMyTrustManagerFactoryParamsmay look like:public interface MyTrustManagerFactoryParams extends
ManagerFactoryParameters {
public boolean getBValue();
public float getRValue();
public String getSValue():
}Some trustmanagers are capable of making trust decisions without having to be explicitly initialized with a KeyStore object or any other parameters. For example, they may access trust material from a local directory service via LDAP, may use a remote online certificate status checking server, or may access default trust material from a standard local location.
PKIX TrustManager Support
As of the 1.4.2 release of the Java 2 platform, a CertPath-based X.509 trust manager factory called "SunPKIX" was added. SunPKIX was available in addition to the default but simpler X.509 trust manager factory known as "SunX509".
In J2SE 5, SunPKIX is now the default X509TrustManagerFactory. It is selected by the
ssl.TrustManagerFactory.algorithmproperty in thejava.securityfile. (To revert to using the old trust manager, follow the procedure in Customizing the Default Key and Trust Managers to change the property from "PKIX" to "SunX509".) Note that this change only affects applications that use the default trust manager, it does not affect applications that explicitly specify trust managers via SSLContext.init(..., TrustManager[],...). Alternatively, the SunPKIX factory can be accessed programmatically by callingTrustManagerFactory.getInstance("SunPKIX").The PKIX trust manager factory uses the CertPath PKIX implementation from an installed security provider; a "SUN" CertPath provider is supplied with the J2SE 5 Development Kit. The trust manager factory can be initialized using the normal
init(KeyStore ks)method, or by passing CertPath parameters to the the PKIX trust manager using the newly introduced class javax.net.ssl.CertPathTrustManagerParameters.Here is an example of how to get the trust manager to use a particular LDAP certificate store and enable revocation checking.
import javax.net.ssl.*; import java.security.cert.*; import java.security.KeyStore; ... // Create PKIX parameters KeyStore anchors = KeyStore.getInstance("JKS"); anchors.load(new FileInputStream(anc