JavaTM Secure Socket Extension (JSSE)
IBMJSSE2 Provider
Reference Guide
for the Java 2 SDK, Standard Edition, v 5
Copyright Information
Note: Before using this information and the product it supports, be sure to read the general information under Notices.
(c) Copyright Sun Microsystems, Inc. 1998, 2005, 901 San Antonio Rd., Palo Ato, CA 94303 USA. All rights reserved.
(c) Copyright International Business Machines Corporation, 1998, 2005. All rights reserved.
U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- Introduction
- Features and Benefits
- JSSE Standard API
- IBMJSSE2 Provider
- What's New
- Known Differences Between the Original IBMJSSE and the IBMJSSE2 Provider
- Known Differences Between the IBM JSSE and the Sun JSSE Provider
- Related Documentation
Terms and Definitions
- 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)
- Running the IBMJSSE2 in FIPS Mode
- Enabling FIPS Mode
- Troubleshooting
- Configuration Problems
- Debugging Utilities
- Code Examples
- SSL Server using Hardware Cryptography through a IBMPKCS11Impl provider
- SSL Server using Hardware Accelerator through a IBMPKCS11Impl provider
Appendix A: Standard Names
Appendix B: Provider Pluggability
Introduction
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 that developers can integrate directly into their applications.
JSSE was previously an optional package (standard extension) to the Java 2 SDK, Standard Edition (SDK) versions 1.2 and 1.3. JSSE has now been integrated into the SDK, v 1.4.
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.security and java.net packages 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 limited javax.security.cert certificate API is provided only for backward compatibility with JSSE 1.0.x and should not be used. Instead, use the standard java.security.cert certificate API. Because the socket APIs were based on a blocking I/O model, in SDK 5, a non-blocking SSLEngineAPI 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 IBMJSSE2 implementation in the SDK 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: With the latest U.S. government export regulations, JSSE in SDK 5 allows any JSSE provider be used--as long as it supports the cipher suites shown in the Provider Pluggability list in the Appendix. The TrustManagerFactory and KeyManagerFactory are 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, and SSLEngine)
- 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
Cryptographic Functionality Available With JSSE
|
Cryptographic Algorithm *
|
Cryptographic Process
|
Key Lengths (Bits)
|
|
RSA
|
Authentication and key exchange
|
Dependent upon JCE Provider (authentication) Dependent upon JCE Provider (key exchange) 512 (key exchange) |
|
RC4
|
Bulk encryption
|
128 128 (40 effective)
|
| RC2 |
Bulk encryption |
128 |
|
DES
|
Bulk encryption
|
64 (56 effective) 64 (40 effective)
|
|
Triple DES
|
Bulk encryption
|
192 (112 effective)
|
|
AES
|
Bulk encryption
|
256 128
|
|
Diffie-Hellman
|
Key agreement
|
1024 512
|
|
DSA
|
Authentication
|
1024
|
* Note: The IBMJSSE2 implementation uses the JavaTM IBM Cryptography Extension (JCE) family of providers for all of its cryptographic algorithms.
JSSE Standard API
The JSSE standard API, available in the javax.net, javax.net.ssl and javax.security.cert packages, 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.
IBMJSSE2 Provider
The JDK comes with a JSSE provider named "IBMJSSE2", which comes pre-installed and pre-registered with the JCA. This provider supplies the following cryptographic services:
- 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.
- Support for the PKCS12 and IBMPKCS11KS keystore type.
A table of the cipher suites that IBMJSSE2 supports and all of the reserved names can be found in Appendix A.
What's New
What's New in JSSE in SDK 5
The following change was introduced in the JSSE in version 1.5.0 SR5 of the Java 2 platform.
- When IBMJSSE2 is used as a server, if the SSLv3 protocol is to be used for the handshake, it will no longer agree to use any of the AES cipher suites. Previously, the selection of the cipher suite was independent of the protocol selected so one could do an old-style SSLv3 handshake but a more modern AES cipher suite. The TLS protocol is not affected by this change. This change was required in order to support Microsoft Vista clients.
The following enhancements were made in the JSSE in the Java 2 Platform Standard Edition 5:
In 1.4.2, there were two JSSE providers supplied. In 5.0, the original IBMJSSE provider has been removed and replaced solely with the IBMJSSE2 provider. The IBMJSSE2 provider is now the preregistered JSSE provider in the java.security security properties file that is included in the SDK, V5.0. The deprecated com.ibm.net.ssl classes have been removed along with the com.ibm.net.ssl.internal.www.protocol.handler and com.ibm.net.ssl.www.protocol.handler. See Known Differences between the IBM Original JSSE Provider and the IBMJSSE2 Provider for migration assistance. If an internal default context is used, (e.g. a SSLContext is created by SSLSocketFactory.getDefault() or SSLServerSocketFactory.getDefault()), an SSLContext with protocol of "SSL_TLS" will be implemented. Previously, the default was "SSL". In previous SDKs, anonymous and null cipher suites were enabled by default. As these cipher suites are not recommended to be used due the minimal security they provide, they are now not enabled by default. See Accepting Anonymous Cipher Suites for information about using anonymous cipher suites. The IBMJSSE2 Provider supported hardware cryptography in SDK 1.4.2. In order to be compatible with Sun's PKCS#11 support, a configuration file will now be required, even for code which ran successfully on SDK 1.4.2. This configuration file is specific to each hardware device and JSSE. See Enhanced JCE and hardware accelerator/Smartcard support for information about using hardware cryptography in SDK 5.0.
In SDK 5, a number of networking enhancements were made that affected HTTPS. Here is a summary of them.
- Connect and read timeouts. In SDK 1.4.x, the connect and read timeouts for protocol handlers could be set only by using some implementation-specific properties. In SDK 5, methods were added to URLConnection to allow timeouts to be set.
- Dynamic proxy server configuration and selection. Prior to SDK 5, proxy server configuration was static, global and configured via system properties. SDK 5 introduced new classes to allow proxies to be configured dynamically and on a per-URI basis.
- Pluggable cookie support. Prior to SDK 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 SDK 5 to allow applications to install a handler that can cache URL responses.
For details about these enhancements, see the SDK 5 Release Notes.
SSLEngine and SSLEngineResult were added to support non-blocking I/O. SSLContext and SSLContextSpi were updated to generate SSLEngines. A set of new methods were introduced to HandshakeCompletedEvent, HttpsURLConnection, and SSLSession which allow retrieval of Principals used by a session. (For example: X500Principal for X509 based ciphersuites, KerberosPrincipal for Kerberos suites, etc.) If an attempt is made to obtain the certificate chain for a session which does use certificates (Kerberos cipher suites), a SSLPeerUnverifiedException will occur.
New constructors were added to SSLException to support exception chaining.
A new method was added to SSLSession to 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 using SSLEngine.
A new abstract class X509ExtendedKeyManager was added to provide for SSLEngine extensions of the X509KeyManager interface. SSLContexts require initialization with an X509ExtendedKeyManager before using SSLEngines.
Two ManagerFactoryParameters factory classes were added. CertPathTrustManagerParameters allows passing of validation settings to CertPath-based TrustManagers. KeyStoreBuilderParameters was added to support dynamic key stores. (See the KeyStore.Builder class or the Multiple and Dynamic Keystores section for more information on dynamic KeyStores.)
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 SDK 1.4.2
New IBMJSSE2 Provider The IBMJSSE2 provider is a new provider included in the SDK, v1.4.2. It is not preregistered in the java.security security properties file that is included with the SDK, v1.4.2. This section describes the enhancements that have been added to the new IBMJSSE2 Provider. Note: The IBMJSSE2 provider in SDK 5, is now the preregistered JSSE provider.
The tracing and debugging information supplied has been improved in order to assist with problem determination. The IBM debug JAR file is no longer required when tracing is required. The tracing is now configurable; see Debugging Utilities for more information.
The Java Cryptography Extension (JCE) is a set of packages that provides a framework and implementations for encryption, key generation and key agreement, and message authentication code (MAC) algorithms. The original IBMJSSE Provider used it own internal cryptographic code. The IBMJSSE2 Provider uses the IBM JCE providers, IBMJCE, IBMJCE4758 and IBMPKCS11Impl, exclusively. The IBMJSSE2 provider cannot be configured to use another JCE provider.
Because the IBMJSSE2 provider no longer contains cryptographic code, it is not required to be FIPS certified. It leverages its cryptographic support from the IBMJCEFIPS provider. Support and updates can be applied to JSSE without requiring FIPS recertification, as long as the IBMJCEFIPS is certified. IBM JVM build 1.4.2sr1a or later is required. See "Running IBMJSSE2 in FIPS mode" for more information on setting up JSSE2 to run in FIPS mode.
The IBMJSSE2 provider can be configured to use hardware cryptographic accelerators for potential performance improvements and to use hardware cryptographic cards as keystores for greater flexibility in key and trust management. The IBMJSSE2 provider uses the IBMJCE4758 provider on z/OS to provide hardware cryptographic support and IBMPKCS11Impl on all other platforms. See the IBM Java PKCS11 Implementation Provider for further information on setting up the IBMPKCS11Impl provider and hardware cryptographic cards that it supports. Support in the IBM JCE hardware cryptographic providers also enable access to hardware keystores. To use a hardware keystore or truststore, set the keystore provider to PKCS11IMPLKS, for a PKCS#11 type keystore. Configure the IBM hardware JCE provider and add the IBM hardware JCE provider to the provider list. The IBM hardware JCE provider will now be used for all JSSE cryptographic functions including the handling of the cryptographic hardware keys in the keystore.
Note 1: IBMJSSE2 is now dependent upon the hardware configuration file which is specific for each hardware cryptographic card. IBMJSSE2 will not be able to support hardware properly without the proper configuration file. Applications which ran in SDK 1.4.2, will need to be modified in include the proper configuration file for SDK 5.0.
Note 2: In order to use IBM hardware crypto, the IBM hardware JCE provider (PKCS11Impl) must be before the software IBM JCE provider. See the IBM Java PKCS11 Implementation Provider and the sample configuration files for further information.
In addition to the simple X.509-based trustmanager previously available in the IBMJSSE provider, the IBMJSSE2 provider now supports a second, PKIX-compliant trust manager. It is implemented using the default CertPath PKIX implementation. For more information, see TrustManagerFactory Class.
The known differences between the original JSSE provider and the new IBMJSSE2 provider are as follows. Code written to the original IBM JSSE provider might not compile or execute exactly as it did before.
- IBMJSSE2 Provider is called
com.ibm.jsse2.IBMJSSEProvider2. In 5.0, it is pre-registered in the provider list.
- IBMJSSE2 provider HTTPS protocol handler is called
com.ibm.net.ssl.www2.protocol.Handler.
- IBMJSSE2 provider does not support the com.ibm.net.ssl framework. Use the javax.net.ssl framework instead.
- IBMJSSE2 provider does not support the SSL version 2 protocol. The server side of a JSSE2 connection does accept
SSLv2Hello.
- The AES_256 ciphers require the installation of the JCE Unlimited Strength Jurisdiction Policy. The original JSSE did not use JCE for its cryptographic support and therefore did not require these files.
- IBMJSSE2 provider requires an IBM JCE provider.
- IBMJSSE2 does not build the private key certificate chain from the trusted keystore. The trusted certificates must be added to the private key to complete the chain. This is an incompatible change.
- IBMJSSE2 provider considers a certificate trusted if you have the private key.
- The IBMJSSE2 HTTPS performs hostname verification and rejects requests where a mismatch occurs between the host that you will connect to and the server name from the certificate. A HostnameVerification implementation called
com.ibm.jsse2.HostnameVerifierIgnore is provided to always accept the connection even when a mismatch occurs.
- Tracing no longer requires the debug version of the IBMJSSE2 provider.
- The IBMJSSE2 implementation supports the new TrustManager which implements rules for the certificate chain path validation that Sun added to 1.4.2.
- The class
com.ibm.jsse.KeyManagerFactoryParametersSpec(KeyStore ks, char[] password, String jceprovider) which was implemented for the IBMJCE4758 keystore has been removed. Convert code to use the IBMJCE4758KS directly through the keystore API and the IBMJCE4758 provider. (Applies to z/OS only.)
- The class com.ibm.jsse.SSLContext that is used to access secure token has been removed. Convert code that accesses token types of PKCS#12 to use the keystore API directory with a PKCS12 keystore type. Convert code that accesses token types of PKCS#11 to use the IBMPKCS11Impl JCE provider and IBMPKCS11ImplKS directly through the keystore API. Code that must use the PKCS#7 and MSCAPI token cannot use the new JSSE provider.
- IBMJSSE2 running in FIPS mode does not require a separate jar.
- IBMJSSE2 performs asynchronous key renegotiation. IBMJSSE performed synchronous key renegotation.
Known Differences between the IBMJSSE2 Provider and the Sun JSSE Provider
The known differences between the IBM JSSE and the Sun JSSE implementation are as follows. They do not affect API specifications or JSSE architecture. See the appropriate sections of the document for details.
- IBM JSSE provider is called
com.ibm.jsse2.IBMJSSEProvider2.
- IBM KeyManagerFactory is called
IbmX509.
- IBM TrustManagerFactory is called
IbmX509 or IbmPKIX.
- IBM HTTPS protocol handler is called
com.ibm.net.ssl.www2.protocol.Handler.
- The IBMJSSE2 provider does not support the com.sun.net.ssl framework. Use the javax.net.ssl framework instead.
- PKIK revocation checking can be used by setting the system property
com.ibm.jsse2.checkRevocation to true.
- IBM implementation supports the following protocols:
SSL, SSLv3, TLS, TLSv1, and SSL_TLS for engine class SSLContext or the API setEnabledProtocols in the SSLSocket or SSLServerSocket classes. It does not support specifying SSLv2Hello. A server side connection always accepts an SSLv2Hello. The IBM SSLContext getInstance factory method can be used to control which protocols actually get enabled for an SSL connection. Using the SSLContext getInstance or the setEnabledProtocols method give the same result. The Sun JSSE controls which protocols are actually enabled for an SSL connection through setEnabledProtocols.
- IBM and Sun support different ciphers. See Supported Cipher Suites for list of ciphers the IBM JSSE supports.
- The IBM JSSE TrustManager does not allow anonymous ciphers. In order to handshake on an anonymous cipher, a custom TrustManager that allows anonymous ciphers must be provided. See Accepting Anonymous Cipher Suites for information about creating your own X509TrustManager.
- When a null KeyManager is passed to SSLContext, the IBM JSSE KeyManagerFactory implemention will check system properties, then jssecacerts, if it exists, and finally use cacerts file to find the key material. The Sun JSSE will create an empty KeyManager. See KeyManager Class for further information.
- The IBM JSSE X509TrustManager and X509KeyManager will throw an exception if the TrustStore or KeyStore that is specified by system properties does not exist, of if the password is incorrect or the keystore type is inappropriate for the actual keystore. The Sun X509TrustManager will create a default TrustManager or KeyManager with an empty keystore.
- The IBM JSSE implementation will verify the entire server or client certificate chain, including trusted certificates. For example, if a trusted certificate has expired, the handshake will fail, even though the expired certificate is trusted. The Sun JSSE will verify the certificate chain up to the trusted certificate. Verification will stop when it reaches a trusted certificate and the trusted certificate and beyond will not be verified.
- For the Sun implementation: DSA server certificates can use only *_DH*_* cipher suites. For the IBM implementation, if the Server has a DSA certificate only and only RSA* ciphers are enabled, the connection succeeds with an RSA cipher. DSA will be used for authentication and ephemeral RSA will be used for the key exchange.
- Sun does not provide a JSSE that supports FIPS.
Related Documentation
Java Secure Socket Extension Documentation
Java 2 Platform Security Documentation
Export Issues Related to Cryptography
For information on U.S. encryption policies, refer to these Web sites:
Cryptography Documentation
Online resources:
Books:
- 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:
Books:
- 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.
- Enterprise Java Security: Building Secure J2EE Applications, by Marco Pistoia, Nataraj Nagaratnam, Larry Koved, and Anthony Nadalin. Addison Wesley, 2004.
Terms and Definitions
There are several terms relating to cryptography that are used within this document. This section defines some of these terms.
AuthenticationAuthentication is the process of confirming the identity of a party with whom one is communicating. 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, and so on). 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 in this format, and certificates in this format can be managed by the JDK 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 DecryptionEncryption 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 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 AgreementKey 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, for example, 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 the IBM "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 be added only 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 as a result 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 CryptographyPublic 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 CryptographySecret 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 that 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) Protocol Overview
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. After 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.
After 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 integrity 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.
When 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. When 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, secret key encryption 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/SSLEngines you should always check the peer's credentials before sending any data. The SSLSocket and SSLEngine classes 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 HostnameVerifier to override the default HTTPS hostname rules. See HttpsURLConnection for more information.
SSL and TLS References
For a list of resources containing more information about SSL, see Secure Sockets Layer Documentation .
Key Classes
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 SSLSocket and SSLEngine. In the diagram below, the major classes used to create SSLSocket/SSLEngines are laid out in a logical ordering.
An SSLSocket is created either by an SSLSocketFactory or by an SSLServerSocket accepting an in-bound connection. (In turn, an SSLServerSocket is created by an SSLServerSocketFactory.) Both SSLSocketFactory and SSLServerSocketFactory objects are created by an SSLContext. An SSLEngine is created directly by the SSLContext, and relies on the application to handle all I/O.
IMPORTANT NOTE: When using raw SSLSockets/SSLEngines you should always check the peer's credentials before sending any data. The SSLSocket/SSLEngine classes 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
getDefault method on either the SSLSocketFactory or SSLServerSocketFactory class. These methods create a default SSLContext with a default KeyManager, TrustManager, default SSL provider, and a secure random number generator. (A default KeyManagerFactory and TrustManagerFactory are used to create the KeyManager and TrustManager, respectively.) The key material used is found in the default keystore or 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
getInstance on the SSLContext class, then initialize the context by calling the instance's proper init method. One variant of the init method takes three arguments: an array of KeyManager objects, an array of TrustManager objects, and a SecureRandom random number generator. The KeyManager and TrustManager objects are created by either implementing the appropriate interface(s) or using the KeyManagerFactory and TrustManagerFactory classes to generate implementations. The KeyManagerFactory and TrustManagerFactory can then each be initialized with key material contained in the KeyStore passed as an argument to the TrustManagerFactory and KeyManagerFactory init method. Finally, the getTrustManagers method (in TrustManagerFactory) and getKeyManagers method (in KeyManagerFactory) 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 SSLSession is created which contains various information, such as identities established, cipher suite used, and so on. The SSLSession is 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.net and javax.net.ssl packages.
SocketFactory and ServerSocketFactory Classes
The abstract javax.net.SocketFactory class 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.ServerSocketFactory class is analogous to the SocketFactory class, 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 (or javax.net.ssl.SSLSocket), so that they can directly expose new APIs for features such as compression, security, record marking, statistics collection, or firewall tunneling.
SSLSocketFactory and SSLServerSocketFactory Classes
A javax.net.ssl.SSLSocketFactory acts as a factory for creating secure sockets. This class is an abstract subclass of javax.net.SocketFactory.
Secure socket factories encapsulate the details of creating and initially configuring secure sockets. This encapsulation includes authentication keys, peer certificate validation, enabled cipher suites and so on.
The javax.net.ssl.SSLServerSocketFactory class is analogous to the SSLSocketFactory class, but is used specifically for creating server sockets.
Obtaining an SSLSocketFactory
There are three primary ways of obtaining an SSLSocketFactory:
- Get the default factory by calling the
SSLSocketFactory.getDefault static method.
- Receive a factory as an API parameter. That is, code that needs to create sockets but that doesn't care about the details of how the sockets are configured can include a method with an
SSLSocketFactory parameter that can be called by clients to specify which SSLSocketFactory to 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 that create and use sockets do not need to know the details of socket creation behavior. Creating sockets through a socket factory that is 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.
SSLSocket and SSLServerSocket Classes
The javax.net.ssl.SSLSocket class is a subclass of the standard Java java.net.Socket class. It supports all of the standard socket methods and adds additional methods specific to secure sockets. Instances of this class encapsulate the SSLContext under 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.SSLServerSocket class is analogous to the SSLSocket class, 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 IBM JSSE implementation, the available() method on the object obtained by SSLSocket.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 SSLSocket
Instances of SSLSocket can be obtained in two ways. First, an SSLSocket can be created by an instance of SSLSocketFactory via one of the several createSocket methods on that class. The second way to obtain SSLSockets is through the accept method on the SSLServerSocket class.
SSL/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 SDK 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 SSLSocketChannel which extends java.nio.channels.SocketChannel?" There are two main reasons:
- There were a lot of very difficult questions about what a
SSLSocketChannel should be, including its class hierarchy and how it should interoperate with Selectors and other types of SocketChannels. 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.
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.
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.
SSLEngine
The 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.
- 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.
These five states are decribed in more detail in the SSLEngine class documentation.
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("IbmX509");
kmf.init(ksKeys, passphrase);
// TrustManager's decide whether to allow connections.
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("IbmX509");
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:
client |
SSL/TLS message |
HSStatus |
wrap() |
ClientHello |
NEED_UNWRAP |
unwrap() |
ServerHello/Cert/ServerHelloDone |
NEED_WRAP |
wrap() |
ClientKeyExchange |
NEED_WRAP |
wrap() |
ChangeCipherSpec |
NEED_WRAP |
wrap() |
Finished |
NEED_UNWRAP |
unwrap() |
ChangeCipherSpec |
NEED_UNWRAP |
unwrap() |
Finished |
FINISHED |
Now that handshaking is complete, further calls to wrap() will attempt to consume application data and packages it for transport. unwrap() attempts the opposite.
To 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.
// 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
...
}
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.
// 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.
if (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
Runnable task;
while ((task=engine.getDelegatedTask()) != null) {
new Thread(task).start();
}
}
The engine will block future wrap/unwrap calls 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.
// 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 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. 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.
SSLSession Interface
A javax.net.ssl.SSLSession represents a security context negotiated between the two peers of an SSLSocket/SSLEngine connection. Once a session has been arranged, it can be shared by future SSLSocket/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 an SSLSocket/SSLEngine. The value of this master secret is known only to the underlying secure socket implementation and is not exposed through the SSLSession API.
HttpsURLConnection Class
The https protocol is similar to http, but https first establishes a secure channel using SSL/TLS sockets and then verifies the identity of the peer before requesting/receiving data. The javax.net.ssl.HttpsURLConnection extends the java.net.HttpsURLConnection class, and adds support for https-specific features. See the java.net.URL, java.net.URLConnection, java.net.HttpURLConnection, and javax.net.ssl.HttpURLConnection classes for more information about how https URLs are constructed and used. After obtaining a HttpsURLConnection, you can configure a number of http or https parameters before actually initiating the network connection using the method URLConnection.connect. Of particular interest are:
Setting the Assigned SSLSocketFactory
In some situations, it is desirable to specify the SSLSocketFactory that an HttpsURLConnection instance uses. For example, you may wish to tunnel through a proxy type that isn't supported by the default implementation. The new SSLSocketFactory could return sockets that have already performed all necessary tunneling, thereby allowing HttpsURLConnection to use additional proxies.
The HttpsURLConnection class has a default SSLSocketFactory which is assigned when the class is loaded. (In particular it is the factory returned by the method SSLSocketFactory.getDefault.) Future instances of HttpsURLConnection will inherit the current default SSLSocketFactory until a new default SSLSocketFactory is assigned to the class using the static method HttpsURLConnection.setDefaultSSLSocketFactory. Once an instance of HttpsURLConnection has been created, the inherited SSLSocketFactory on this instance can be overriden with a call to the setSSLSocketFactory method.
Note that changing the default static SSLSocketFactory has no effect on existing instances of HttpsURLConnections, a call to the setSSLSocketFactory method is necessary to change the existing instance.
One can obtain the per-instance or per-class SSLSocketFactory by making a call to the getSSLSocketFactory/getDefaultSSLSocketFactory methods, respectively.
Setting the Assigned HostnameVerifier
If the hostname of the URL does not match the hostname in the credentials received as part of the SSL or TLS handshake, it is 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 assigned HostnameVerifier for 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/setDefaultHostnameVerifier methods operate in a similar manner to the setSSLSocketFactory/setDefaultSSLSocketFactory methods, in that there are HostnameVerifiers assigned on a per-instance and per-class basis, and the current values can be obtained by a call to the getHostnameVerifier/ getDefaultHostnameVerifier methods.
Support Classes and Interfaces
The classes and interfaces in this section are provided to support the creation and initialization of SSLContext objects, which are used to create SSLSocketFactory, SSLServerSocketFactory, and SSLEngine objects. The support classes and interfaces are part of the javax.net.ssl package.
Three of the classes described in this section ( SSLContext, KeyManagerFactory, and TrustManagerFactory) are engine classes. An engine class is an API class for specific algorithms (or protocols, in the case of SSLContext), 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 Java TM Cryptography Architecture API Specification & Reference.
The IBMJSSE2 provider that comes standard with JSSE provides SSLContext, KeyManagerFactory, and TrustManagerFactory implementations, as well as implementations for engine classes in the standard Java security (java.security) API. The implementations supplied by IBMJSSE2 are:
Engine Class Algorithm or
Implemented Protocol
KeyManagerFactory "IbmX509", "NewIbmX509"
TrustManagerFactory "IbmPKIX" (aka "X509"/"PKIX"), "IbmX509"
SSLContext "SSLv3"
SSLContext "SSL"
SSLContext "TLSv1"
SSLContext "TLS"
SSLContext "SSL_TLS"
SSLContext Class
The javax.net.ssl.SSLContext is 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. An SSLContext holds all of the state information shared across all objects created under that context. For example, session state is associated with the SSLContext when 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 init method 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 SSLContext Object
Like other JCA provider-based "engine" classes, SSLContext objects are created using the getInstance factory methods of the SSLContext class. These static methods each return an instance that implements the requested secure socket protocol. The returned instance can implement other protocols too. For example, getInstance("SSL_TLS") returns an instance which implements "SSLv3", "TLSv1" and can receive a SSLv2Hello. The getInstance("SSL") returns and instance which implements "SSLv3" and receives a SSLv2Hello, while the getInstance("SSLv3") returns and instance which only implements "SSLv3". The getSupportedProtocols method returns a list of supported protocols when an SSLSocket, SSLServerSocket or SSLEngine is created from this context. You can also control which protocols are enabled for an SSL connection by using the method setEnabledProtocols(String[] protocols). Note: An SSLContext object is automatically created, initialized, and statically assigned to the SSLSocketFactory class when you call SSLSocketFactory.getDefault. Therefore, you don't have to directly create and initialize an SSLContext object (unless you want to override the default behavior).
To create an SSLContext object by calling a getInstance factory 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 only a protocol name is specified, the system will determine if there is an implementation of the requested protocol available in the environment If there is more than one, it will determine the 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_TLS") that describes the secure socket protocol desired. Common protocol names for SSLContext objects are defined in Appendix A.
Here is an example of obtaining an SSLContext:
SSLContext sc = SSLContext.getInstance("SSL_TLS");
A newly-created SSLContext should be initialized by calling the init method:
public void init(KeyManager[] km, TrustManager[] tm,
SecureRandom random);
If the KeyManager[] paramater is null, the installed security providers will be searched for the highest-priority implementation of the KeyManagerFactory, from which an appropriate KeyManager will be obtained. If the TrustManager[] parameter is null, the installed security providers will be searched for the highest-priority implementation of the TrustManagerFactory, from which an appropriate TrustManager will 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 SSLContext is created by SSLSocketFactory.getDefault() or SSLServerSocketFactory.getDefault()), a default KeyManager and a TrustManager are created. The default SecureRandom implementation is also chosen.
TrustManager Interface
The primary responsibility of the TrustManager is 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 an SSLContext object with one or more TrustManagers. You need to pass one TrustManager for each authentication mechanism that is supported. If null is passed into the SSLContext initialization, 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 a TrustManagerFactory, or by providing a concrete implementation of the interface.
TrustManagerFactory Class
The javax.net.ssl.TrustManagerFactory is an engine class for a provider-based service that acts as a factory for one or more types of TrustManager objects. 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 TrustManagerFactory
You create an instance of this class in a similar manner to SSLContext, except for passing an algorithm name string instead of a protocol name to the getInstance method: 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",
"IBMJSSE2");
The above call will create an instance of the IBMJSSE2 provider'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 the CertPath API. (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 the X509TrustManager interface.
A newly-created factory should be initialized by calling one of the init methods:
public void init(KeyStore ks); public void init(ManagerFactoryParameters spec);
You should call whichever init method is appropriate for the TrustManagerFactory you are using. (Ask the provider vendor.)
For many factories, such as the "IbmX509" TrustManagerFactory from the IBMJSSE2 provider, the KeyStore is the only information required in order to initialize the TrustManagerFactory and so the first init method is the appropriate one to call. The TrustManagerFactory will query the KeyStore for information on which remote certificates should be trusted during authorization checks.
In some cases, initialization parameters other than a KeyStore might be needed by a provider. Users of that particular provider are expected to pass an implementation of the appropriate ManagerFactoryParameters as defined by the provider. The provider can then call the specified methods in the ManagerFactoryParameters implementation to obtain the needed information.
For example, suppose the TrustManagerFactory provider requires initialization parameters B, R, and S from any application that wants 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 particular ManagerFactoryParameters sub-interface. In our example, suppose the provider requires that the calling application implement and create an instance of MyTrustManagerFactoryParams and pass it to the second init. Here is what MyTrustManagerFactoryParams may 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.
As of the 1.4.2 release of the Java 2 platform, a CertPath-based X.509 trust manager factory called "IbmPKIX" was added. IbmPKIX was available in addition to the default but simpler X.509 trust manager factory known as "IbmX509".
In SDK 5, IbmPKIX is now the default X509TrustManagerFactory. It is selected by the ssl.TrustManagerFactory.algorithm property in the java.security file. (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 "IbmX509 ".) 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 IbmPKIX factory can be accessed programmatically by calling TrustManagerFactory.getInstance( "IbmPKIX").
The PKIX trust manager factory uses the CertPath PKIX implementation from an installed security provider; a "IBM" CertPath provider is supplied with the SDK 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(anchorsFile));
CertPathParameters pkixParams = new PKIXBuilderParameters(anchors,
new X509CertSelector());
// Specify LDAP certificate store to use
LDAPCertStoreParameters lcsp = new LDAPCertStoreParameters("ldap.imc.org",
389);
pkixParams.addCertStore(CertStore.getInstance("LDAP", lcsp));
// Specify that revocation checking is to be enabled
pkixParams.setRevocationEnabled(true);
// Wrap them as trust manager parameters
ManagerFactoryParameters trustParams =
new CertPathTrustManagerParameters(pkixParams);
// Create TrustManagerFactory for PKIX-compliant trust managers
TrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX");
// Pass parameters to factory to be passed to CertPath implementation
factory.init(trustParams);
// Use factory
SSLContext ctx = SSLContext.getInstance("SSL_TLS");
ctx.init(null, factory.getTrustManagers(), null);
If the init(KeyStore ks) method is used, default PKIXParameters are used with the exception that revocation checking is disabled. It can be enabled by setting the system property com.ibm.net.ssl.checkRevocation to true. Note that this setting requires that the CertPath implementation can locate revocation information by itself. The PKIX implementation in the IBM provider can do this in many cases but requires that the system property com.ibm.security.enableCRLDP be set to true.
More information about PKIX and the CertPath API can be found in the Java Certificate Path API Programming Guide.
X509TrustManager Interface
The javax.net.ssl.X509TrustManager interface extends the general TrustManager interface. This interface must be implemented by a trust manager when using X.509-based authentication.
In order to support X.509 authentication of remote socket peers through JSSE, an instance of this interface must be passed to the init method of an SSLContext object.
Creating an X509TrustManager
You can either implement this interface directly yourself or obtain one from a provider-based TrustManagerFactory (such as that supplied by the IBMJSSE2 provider). You could also implement your own interface that delegates to a factory-generated trust manager. For example, you might do this in order to filter the resulting trust decisions and query an end-user through a graphical user interface. Note: If a null KeyStore parameter is passed to the IBMJSSE2 "IbmX509" or "IbmPKIX" TrustManagerFactory, the factory uses the following steps to try to find trust material:
- If the system property:
javax.net.ssl.trustStore
is defined, then the TrustManagerFactory attempts to find a file using the filename specified by that system property, and uses that file for the KeyStore. If the javax.net.ssl.trustStorePassword system property is also defined, its value is used to check the integrity of the data in the truststore before opening it. If javax.net.ssl.trustStore is defined but the specified file does not exist, if a password was specified and it is incorrect, or the keystore type was inappropriate for the truststore, then an error is thrown.
- If the
javax.net.ssl.trustStore system property was not specified, then if the file <java-home>/lib/security/jssecacerts
exists, that file is used. (See The Installation Directory <java-home> for information about what <java-home> refers to.) Otherwise,
- Else the following file is used:
<java-home>/lib/security/cacerts
The factory looks for a file specified via the security property javax.net.ssl.trustStore or for the jssecacerts file before checking for a cacerts file so that you can provide a JSSE-specific set of trusted root certificates separate from ones that might be present in cacerts for code-signing purposes.
Creating Your Own X509TrustManager
If the supplied X509TrustManager behavior isn't suitable for your situation, you can create your own X509TrustManager by either creating and registering your own TrustManagerFactory or by implementing the X509TrustManager interface directly. The following MyX509TrustManager class enhances the default IBMJSSE2 X509 TrustManager behavior by providing alternative authentication logic when the default IBMJSSE2 X509 TrustManager fails.
class MyX509TrustManager implements X509TrustManager {
/*
* The default X509TrustManager returned by IbmX509. We'll delegate
* decisions to it, and fall back to the logic in this class if the
* default X509TrustManager doesn't trust it.
*/
X509TrustManager ibmJSSEX509TrustManager;
MyX509TrustManager() throws Exception {
// create a "default" JSSE X509TrustManager.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("trustedCerts"),
"passphrase".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("IbmX509", "IBMJSSE2");
tmf.init(ks);
TrustManager tms [] = tmf.getTrustManagers();
/*
* Iterate over the returned trustmanagers, look
* for an instance of X509TrustManager. If found,
* use that as our "default" trust manager.
*/
for (int i = 0; i < tms.length; i++) {
if (tms[i] instanceof X509TrustManager) {
ibmJSSEX509TrustManager = (X509TrustManager) tms[i];
return;
}
}
/*
* Find some other way to initialize, or else we have to fail the
* constructor.
*/
throw new Exception("Couldn't initialize");
}
/*
* Delegate to the default trust manager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
ibmJSSEX509TrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
/*
* Delegate to the default trust manager.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
ibmJSSEX509TrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException excep) {
/*
* Possibly pop up a dialog box asking whether to trust the
* cert chain.
*/
}
}
/*
* Merely pass this through.
*/
public X509Certificate[] getAcceptedIssuers() {
return ibmJSSEX509TrustManager.getAcceptedIssuers();
}
}
Once you have created such a trust manager, assign it to an SSLContext via the init method. Future SocketFactories created from this SSLContext will use your new TrustManager when making trust decisions.
TrustManager[] myTMs = new TrustManager [] {
new MyX509TrustManager() };
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, myTMs, null);
Accepting Anonymous Cipher Suites You can enhance MyX509Trustmanager to accept anonymous cipher suites. Enhance checkServerTrusted to verify that it is appropriate to accept this anonymous cipher and return. Your new TrustManager will now accept anonymous cipher suites.
Updating the keyStore Dynamically
You can enhance MyX509TrustManager to handle dynamic keystore updates. When a checkClientTrusted or checkServerTrusted test fails and does not establish a trusted certificate chain, you can add the required trusted certificate to the keystore. You need to create a new ibmX509TrustManager from the TrustManagerFactory initialized with the updated keystore. When you establish a new connection (using the previously initialized SSLContext), the newly added certificate will be called to make the trust decisions.
KeyManager Interface
The primary responsibility of the KeyManager is to select the authentication credentials that will eventually be sent to the remote host. To authenticate yourself (a local secure socket peer) to a remote peer, you need to initialize an SSLContext object with one or more KeyManagers. You need to pass one KeyManager for each different authentication mechanism that will be supported. If null is passed into the SSLContext initialization, a default KeyManager will be created. If the internal default context is used (e.g. a SSLContext created by SSLSocketFactory.getDefault() or SSLServerSocketFactory.getDefault()), a default KeyManager is created. Typically, there is a single key manager that supports authentication based on X.509 public key certificates. Some secure socket implementations may also support authentication based on shared secret keys, Kerberos, or other mechanisms.
KeyManagers are created either by a KeyManagerFactory, or by providing a concrete implementation of the interface.
KeyManagerFactory Class
javax.net.ssl.KeyManagerFactory is an engine class for a provider-based service that acts as a factory for one or more types of KeyManager objects. The IBMJSSE2 provider implements a factory which can return a basic X.509 key manager. Because it is provider-based, additional factories can be implemented and configured to provide additional or alternate key managers.
Creating a KeyManagerFactory
You create an instance of this class in a manner similar to SSLContext, except for passing an algorithm name string instead of a protocol name to the getInstance method: public static KeyManagerFactory getInstance(String
algorithm);
public static KeyManagerFactory getInstance(String algorithm, String provider);
public static KeyManagerFactory getInstance(String algorithm, Provider provider);
A sample algorithm name string is:
"IbmX509"
A sample call is the following:
KeyManagerFactory kmf = KeyManagerFactory.getInstance("IbmX509",
"IBMJSSE2");
The above call will create an instance of the IBMJSSE2 provider's default key manager factory, which provides basic X.509-based authentication keys.
A newly-created factory should be initialized by calling one of the init methods:
public void init(KeyStore ks, char[] password); public void init(ManagerFactoryParameters spec);
You should call whichever init method is appropriate for the KeyManagerFactory you are using. (Ask the provider vendor.)
For many factories, such as the default "IbmX509" KeyManagerFactory from the IBMJSSE2 provider, the KeyStore and password are the only information required in order to initialize the KeyManagerFactory and thus the first init method is the appropriate one to call. The KeyManagerFactory will query the KeyStore for information on which private key and matching public key certificates should be used for authenticating to a remote socket peer. The password parameter specifies the password that will be used with the methods for accessing keys from the KeyStore. All keys in the KeyStore must be protected by the same password.
In some cases, initialization parameters other than a KeyStore and password may be needed by a provider. Users of that particular provider are expected to pass an implementation of the appropriate ManagerFactoryParameters as defined by the provider. The provider can then call the specified methods in the ManagerFactoryParameters implementation to obtain the needed information.
Some factories are capable of providing access to authentication material without having to be initialized with a KeyStore object or any other parameters. For example, they may access key material as part of a login mechanism such as one based on JAAS, the Java Authentication and Authorization Service.
As indicated above, the IBMJSSE2 provider supports a "IbmX509" factory that must be initialized with a KeyStore parameter.
X509KeyManager Interface
The javax.net.ssl.X509KeyManager interface extends the general KeyManager interface. It must be implemented by a key manager for X.509-based authentication. In order to support X.509 authentication to remote socket peers through JSSE, an instance of this interface must be passed to the init method of an SSLContext object. Creating an X509KeyManager
You can either implement this interface directly yourself or obtain one from a provider-based KeyManagerFactory (such as those supplied by the IBMJSSE2 provider). You could also implement your own interface that delegates to a factory-generated key manager. For example, you might do this in order to filter the resulting keys and query an end-user through a graphical user interface. Note: If no KeyStore parameter is passed to the IBMJSSE2 default "IbmX509 " KeyManagerFactory, the factory tries to find key material by consulting the system properties
javax.net.ssl.keyStore javax.net.ssl.keyStorePassword javax.net.ssl.keyStoreType
If these properties specify a file with an appropriate password, the factory uses this file for the KeyStore. If that file does not exist, the password is bad, or the keystore type is inappropriate for the KeyStore, then an error is thrown.
- If the
javax.net.ssl.keyStore system property was not specified, then if the file <java-home>/lib/security/jssecacerts
exists, that file is used. (See The Installation Directory <java-home> for information about what <java-home> refers to.) Otherwise,
- Else the following file is used:
<java-home>/lib/security/cacerts
Generally, the process acting as the server in the handshake will need a keystore for its KeyManager in order to obtain credentials for authentication to the client. Unless the server requires client authentication, the process acting as the client will not need a KeyManager keystore.
Creating Your Own X509KeyManager
If the default X509KeyManager behavior isn't suitable for your situation, you can create your own X509KeyManager in a way similiar to that shown in Creating Your Own X509TrustManager.
Relationships between TrustManagers and KeyManagers
Historically there has been confusion regarding the jobs of TrustManagers and KeyManagers interfaces. In summary, here are the primary responsibilities of each manager type:
| Type |
Function |
TrustManager |
Determines whether the remote authentication credentials (and thus the connection) should be trusted. |
KeyManager |
Determines which authentication credentials to send to the remote host. |
Secondary Support Classes and Interfaces
These classes are provided as part of the JSSE API to support the creation, use, and management of secure sockets. They are less likely to be used by secure socket applications than are the core and support classes. The secondary support classes and interfaces are part of the javax.net.ssl and javax.security.cert packages.
SSLSessionContext Interface
A javax.net.ssl.SSLSessionContext is a grouping of SSLSessions associated with a single entity. For example, it could be associated with a server or client that participates in many sessions concurrently. The methods on this interface enable the enumeration of all sessions in a context and allow lookup of specific sessions via their session ids.
An SSLSessionContext may optionally be obtained from an SSLSession by calling the SSLSession getSessionContext method. The context may be unavailable in some environments, in which case the getSessionContext method returns null.
SSLSessionBindingListener Interface
The javax.net.ssl.SSLSessionBindingListener is an interface implemented by objects that want to be notified when they are being bound or unbound from an SSLSession.
SSLSessionBindingEvent Class
A javax.net.ssl.SSLSessionBindingEvent is the event communicated to an SSLSessionBindingListener when it is bound or unbound from an SSLSession.
HandShakeCompletedListener Interface
The javax.net.ssl.HandShakeCompletedListener is an interface implemented by any class that wants to receive notification of the completion of an SSL protocol handshake on a given SSLSocket connection.
HandShakeCompletedEvent Class
A javax.net.ssl.HandShakeCompletedEvent is the event communicated to a HandShakeCompletedListener upon completion of an SSL protocol handshake on a given SSLSocket connection.
HostnameVerifier Interface
If the SSL or TLS implementation's standard hostname verification logic fails, the implementation will call the verify method of the class which implements this interface and is assigned to this HttpsURLConnection instance. If the callback class can determine that the hostname is acceptable given the parameters, it should report that the connection should be allowed. An unacceptable response will cause the connection to be terminated. For example:
public class MyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { // pop up an interactive dialog box // or insert additional matching logic if (good_address) { return true; } else { return false; } } }
//...deleted...
HttpsURLConnection urlc = (HttpsURLConnection) (new URL("https://www.ibm.com/")).openConnection(); urlc.setHostnameVerifier(new MyHostnameVerifier());
See HttpsURLConnection Class for more information on how to assign the HostnameVerifier to the HttpsURLConnection. X509Certificate Class
Many secure socket protocols perform authentication using public key certificates, also called X.509 certificates. This class is the default authentication mechanism for the SSL and TLS protocols.
The java.security.cert.X509Certificate abstract class provides a standard way to access the attributes of X.509 certificates.
Note: The javax.security.cert.X509Certificate class is supported only for backward compatibility with previous (1.0.x and 1.1.x) versions of JSSE. New applications should use java.security.cert.X509Certificate, not javax.security.cert.X509Certificate.
Previous (JSSE 1.0.x) Implementation Classes and Interfaces
In previous (1.0.x) versions of JSSE, there was a reference implementation whose classes and interfaces were provided in the com.ibm.net.ssl package. The classes formally in com.ibm.net.ssl have been promoted to javax.net.ssl package and are now a part of the standard JSSE. The IBMJSSE2 provider does not support these classes.
Customizing JSSE
The Installation Directory <java-home>
The term <java-home> is used throughout this document to refer to the directory where the Java 2 Runtime Environment (JRE) is installed. It is determined based on whether you are running JSSE on a JRE with or without the JavaTM 2 SDK installed. Java 2 SDK includes the JRE, but it is located in a different level in the file hierarchy.
The following are some examples of which directories <java-home> refers to:
- On Solaris, if the Java 2 SDK is installed in
/home/user1/jdk1.5.0, then <java-home> is /home/user1/jdk1.5.0/jre
- On Solaris, if JRE is installed in
/home/user1/jre1.5.0 and the Java 2 SDK is not installed, then <java-home> is /home/user1/jre1.5.0
- On Microsoft Windows platforms, if the Java 2 SDK is installed in
C:\jdk1.5.0, then <java-home> is C:\j2k1.5.0\jre
- On Microsoft Windows platforms, if the JRE is installed in
C:\jre1.5.0 and the Java 2 SDK is not installed, then <java-home> is C:\jre1.5.0
Customization
JSSE includes an implementation that all users can utilize. If desired, it is also possible to customize a number of aspects of JSSE, plugging in different implementations or specifying the default keystore, etc. The table below summarizes which aspects can be customized, what the defaults are, and which mechanisms are used to provide customization. The first column of the table provides links to more detailed descriptions of each designated aspect and how to customize it.
Some of the customizations are done by setting system property or security property values. Sections following the table explain how to set such property values.
IMPORTANT NOTE: Many of the properties shown in this table are currently utilized by the JSSE implementation, but there is no guarantee that they will continue to have the same names and types (system or security) or even that they will exist at all in future releases. All such properties are flagged with an "* ". They are documented here for your convenience for use with the JSSE implementation.
JSSE Customization
|
Customizable Item
|
Default
|
How To Customize
|
| X509Certificate implementation |
X509Certificate implementation from IBM
"com.ibm.security.cert.X509V1CertImpl"
|
cert.provider.x509v1 security property
|
| HTTPS protocol implementation |
Implementation from IBM
"com.ibm.net.ssl.www2.protocol"
|
java.protocol.handler.pkgs system property
|
| provider implementation |
IBMJSSE2 "com.ibm.jsse2.IBMJSSEProvider2" |
A security.provider.n= line in security properties file. See description.
|
| default SSLSocketFactory implementation |
SSLSocketFactory implementation from IBM.
"com.ibm.jsse2.SSLSocketFactoryImpl"
|
** ssl.SocketFactory.provider security property
|
| default SSLServerSocketFactory implementation |
SSLServerSocketFactory implementation from IBM.
"com.ibm.jsse2.SSLServerSocketFactoryImpl"
|
**ssl.ServerSocketFactory.provider security property
|
| default keystore |
If no system property, then jssecacets is the default. Otherwise, cacerts is the default. |
* javax.net.ssl.keyStore system property Note that the value NONE may be specified. This setting is appropriate if the keystore is not file-based (for example, it resides in a hardware token).
|
| default keystore password |
"changeit"
|
* javax.net.ssl.keyStorePassword system property
|
| default keystore provider |
No Default
|
* javax.net.ssl.keyStoreProvider system property
|
| default keystore type |
KeyStore.getDefaultType()
|
* javax.net.ssl.keyStoreType system property
|
| default truststore |
If no system property, then jssecacets is the default. Otherwise, cacerts is the default.
|
* javax.net.ssl.trustStore system property
|
| default truststore password |
No default.
|
*javax.net.ssl.trustStorePassword system property
|
| default truststore provider |
No default.
|
*javax.net.ssl.trustStoreProvider system property
|
| default truststore type |
KeyStore.getDefaultType()
|
* javax.net.ssl.trustStoreType system property Note that the value NONE may be specified. This setting is appropriate if the truststore is not file-based (for example, it resides in a hardware token.)
|
| default key manager factory algorithm name |
IbmX509
|
ssl.KeyManagerFactory.algorithm security property |
| default trust manager factory algorithm name |
PKIX
|
ssl.TrustManagerFactory.algorithm security property |
| default proxy host |
No default.
|
* https.proxyHost system property |
| default proxy port |
80
|
* https.proxyPort system property |
| default ciphersuites |
Determined by the socket factory.
|
* https.cipherSuites system property. This contains a comma-separated list of cipher suite names specifying which cipher suites to enable for use on this HttpsURLConnection. See the SSLSocket setEnabledCipherSuites(String[]) method. |
| default handshaking protocols |
Determined by the socket factory
|
* https.protocols system property. This contains a comma-separated list of protocol suite names specifying which protocol suites to enable on this HttpsURLConnection. See the SSLSocket setEnabledProtocols(String[]) method. |
| default https port |
443
|
* Customize via port field in the https URL. |
| JCE encryption algorithms used by IBMJSSE2 provider |
IBMJCE implementations
|
Give alternate IBM JCE algorithm provider(s) a higher preference order than the IBMJCE provider |
* This property is currently used by the JSSE implementation. It is not guaranteed to be examined and used by other implementations. If it is examined by another implementation, that implementation should handle it in the same manner as the JSSE implementation does. There is no guarantee the property will continue to exist or be of the same type (system or security) in future releases.
** Due to U.S. export restrictions, the JSSE implementations in IBM Java 2 SDK, v1.4 and later do not allow full pluggability, and thus there may be restrictions on replacing the default SSLSocketFactory or SSLServerSocketFactory implementations. Please see the note on pluggability for more information, and check with each targeted deployment platform as to their restrictions. If you are using a JSSE implementation that allows alternate SSL or TLS implementations, do so by setting the specified security properties.
Note that some items are customized by setting java.lang.system properties while others are customized by setting java.security.Security properties. The following sections explain how to set values for both types of properties.
How to Specify a java.lang.system Property
Some aspects of JSSE may be customized by setting system properties. You can set a system property either statically or dynamically:
- To set a system property statically, use the
-D option of the java command. For example, to run an application named MyApp and set the javax.net.ssl.trustStore system property to specify a truststore named "MyCacertsFile ", type the following: java -Djavax.net.ssl.trustStore=MyCacertsFile MyApp
- To set a system property dynamically, call the
java.lang.System.setProperty method in your code substituting the appropriate property name and value: System.setProperty(propertyName, "propertyValue");
For example, a setProperty call corresponding to the previous example for setting the javax.net.ssl.trustStore system property to specify a truststore named "MyCacertsFile" would be: System.setProperty("javax.net.ssl.trustStore", "MyCacertsFile");
How to Specify a java.security.Security Property
Some aspects of JSSE may be customized by setting security properties. You can set a security property either statically or dynamically:
- To set a security property statically, add a line to the security properties file. The security properties file is located at:
<java-home>/lib/security/java.security
where <java-home> refers to the directory where the JRE runtime software is installed, as described in The Installation Directory <java-home>. To specify a security property value in the security properties file, you add a line of the following form:
propertyName=propertyValue
For example, suppose you want to specify a different key manager factory algorithm name than the "IbmX509" default. You do this by specifying the algorithm name as the value of a security property named ssl.KeyManagerFactory.algorithm. Suppose you want to set the value to "MyX509". To do so, place the following in the security properties file:
ssl.KeyManagerFactory.algorithm=MyX509
- To set a security property dynamically, call the
java.security.Security.setProperty method in your code substituting the appropriate property name and value: Security.setProperty(propertyName, "propertyValue");
For example, a setProperty call corresponding to the previous example for specifying the key manager factory algorithm name would be: Security.setProperty("ssl.KeyManagerFactory.algorithm", "MyX509");
Customizing the X509Certificate Implementation
The X509Certificate implementation returned by the X509Certificate.getInstance method is by default the implementation from the JSSE implementation.
You can optionally cause a different implementation to be returned. To do so, specify the name (and package) of the alternate implementation's class as the value of a security property named cert.provider.x509v1. For example, if the class is called MyX509CertificateImpl and it appears in the com.cryptox package, you should place the following in the security properties file:
cert.provider.x509v1=com.cryptox.MyX509CertificateImpl
Specifying an Alternate HTTPS Protocol Implementation
You can communicate securely with an SSL-enabled web server by using the "https" URL scheme for the java.net.URL class. The JDK provides a default https URL implementation.
If you want an alternate https protocol implementation to be used, set the java.protocol.handler.pkgs system property to include the new class name. This action causes the specified classes to be found and loaded before the JDK default classes. See the java.net.URL class documentation for details.
Customizing the Provider Implementation
The SDK 1.4 and later releases come standard with a JSSE Cryptographic Service Provider, or provider for short, named "IBMJSSE" and called "IBMJSSE2" in SDK 5.0. Providers are essentially packages that implement one or more engine classes for specific cryptographic algorithms. The JSSE engine classes are SSLContext, KeyManagerFactory, and TrustManagerFactory. For more information on providers and engine classes, see the "Design Principles" and "Concepts" sections of the Java TM Cryptography Architecture API Specification & Reference.
In order to be used, a provider must be registered, either statically or dynamically. You do not need to register the "IBMJSSE2" provider because it is pre-registered. If you want to use other providers, read the following sections to see how to register them.
Registering the Cryptographic Service Provider Statically
You register a provider statically by adding a line of the following form to the security properties file: security.provider.n=providerClassName
This line declares a provider, and specifies its preference order "n". The preference order is the order in which providers are searched for requested algorithms (when no specific provider is requested). The order is 1-based; 1 is the most preferred, followed by 2, and so on.
The providerClassName is the fully qualified name of the provider class. You get this name from the provider vendor.
To register a provider, add the above line to the security properties file, replacing providerClassName with the fully qualified name of the provider class and substituting n with the priority that you would like to assign to the provider.
The standard security provider and the IBMJSSE2 provider shipped with the Java 2 platform are automatically registered for you; the following lines appear in the java.security security properties file in distributed platforms to register the IBMJCE security provider with preference order 2 and the IBMJSSE2 provider with preference order 1:
security.provider.1=com.ibm.jsse2.IBMJSSEProvider2
security.provider.2=com.ibm.crypto.provider.IBMJCE
security.provider.3=com.ibm.security.jgss.IBMJGSSProvider
security.provider.4=com.ibm.security.cert.IBMCertPath
security.provider.5=com.ibm.security.sasl.IBMSASL
To utilize another JSSE provider, add a line registering the alternate provider, giving it whatever preference order you prefer.
You can have more than one JSSE provider registered at the same time. They might include different implementations for different algorithms for different engine classes, or they might have support for some or all of the same types of algorithms and engine classes. When a particular engine class implementation for a particular algorithm is searched for, if no specific provider is specified for the search, the providers are searched in preference order and the implementation from the first provider that supplies an implementation for the specified algorithm is used.
Registering the Cryptographic Service Provider Dynamically
Instead of registering a provider statically, you can add the provider dynamically at runtime by calling the Security.addProvider method at the beginning of your program. For example, to dynamically add a provider whose Provider class name is MyProvider and whose MyProvider class resides in the com.ABC package, you would call:
Security.addProvider( new com.ABC.MyProvider());
The Security.addProvider method adds the specified provider to the next available preference position.
This type of registration is not persistent and can only be done by a program with sufficient permissions.
Customizing the Default Key and Trust Stores, Store Types, and Store Passwords
Whenever a default SSLSocketFactory or SSLServerSocketFactory is created (via a call to SSLSocketFactory.getDefault or SSLServerSocketFactory.getDefault), and this default SSLSocketFactory (or SSLServerSocketFactory) comes from the JSSE reference implementation, a default SSLContext is associated with the socket factory. (The default socket factory will come from the JSSE implementation.)
This default SSLContext is initialized with a default KeyManager and a TrustManager. If a keystore is specified by the javax.net.ssl.keyStore system property, then the KeyManager created by the default SSLContext will be a KeyManager implementation for managing the specified keystore. In this case, if such a property exists but the file it specifies doesn't, then an error will be thrown. If no javax.net.ssl.keyStore property exists, then a default keystore is searched for. If a keystore named <java-home>/lib/security/jssecacerts is found, it is used. If not, then a keystore named <java-home>/lib/security/cacerts is searched for and used (it must exist).If a keystore is specified by the javax.net.ssl.keyStore system property, then the KeyManager created by the default SSLContext will be a KeyManager implementation for managing the specified keystore. (The actual implementation will be as specified in Customizing the Default Key and Trust Managers.)
Similarly, if a truststore is specified by the javax.net.ssl.trustStore system property, then the TrustManager created by the default SSLContext will be a TrustManager implementation for managing the specified truststore. In this case, if such a property exists but the file it specifies doesn't, then an error will be thrown. If no javax.net.ssl.trustStore property exists, then a default truststore is searched for. If a truststore named <java-home>/lib/security/jssecacerts is found, it is used. If not, then a truststore named <java-home>/lib/security/cacerts is searched for and used (it must exist). See The Installation Directory <java-home> for information as to what <java-home> refers to.
IMPORTANT NOTE: The JDK ships with a limited number of trusted root certificates in the <java-home>/lib/security/cacerts file. As documented in keytool, it is your responsibility to maintain (that is, add and remove) the certificates contained in this file if you use this file as a truststore. Depending on the certificate configuration of the servers you contact, you may need to add additional root certificate(s). Obtain the needed specific root certificate(s) from the appropriate vendor.
If system properties javax.net.ssl.keyStoreType, or javax.net.ssl.keyStorePassword, or both are also specified, they are treated as the default KeyManager keystore type and password, respectively. If there is no type specified, the default type is that returned by KeyStore.getDefaultType(), which is the value of the keystore.type security property, or "jks" if no such security property is specified. If there is no keystore password specified, it is assumed to be "changeit".
Similarly, if system properties javax.net.ssl.trustStoreType or javax.net.ssl.trustStorePassword, or both are also specified, they are treated as the default truststore type and password, respectively. If there is no type specified, the default type is that returned by KeyStore.getDefaultType(). If there is no truststore password specified, it is assumed to be "".
Important Note: This section describes the current JSSE reference implementation behavior. The system properties described in this section are not guaranteed to continue to have the same names and types (system or security) or even to exist at all in future releases. They are also not guaranteed to be examined and used by any other JSSE implementations. If they are examined by an implementation, that implementation should handle them in the same manner as the JSSE reference implementation does, as described herein.
Customizing the Default Key and Trust Managers
As noted in Customizing the Default Key and Trust Stores, Store Types, and Store Passwords, whenever a default SSLSocketFactory or SSLServerSocketFactory is created, and this default SSLSocketFactory (or SSLServerSocketFactory) comes from the JSSE reference implementation, a default SSLContext is associated with the socket factory.
This default SSLContext is initialized with a KeyManager and a TrustManager. The KeyManager or TrustManager or both, supplied to the default SSLContext will be a KeyManager or TrustManager implementation for managing the specified keystore or truststore, as described in the aforementioned section.
The KeyManager implementation selected is determined by first examining the security property:
ssl.KeyManagerFactory.algorithm
If such a property value is specified, a KeyManagerFactory implementation for the specified algorithm is searched for. The implementation from the first provider that supplies an implementation is used. Its getKeyManagers method is called to determine the KeyManager to supply to the default SSLContext. (Technically, getKeyManagers returns an array of KeyManagers, one KeyManager for each type of key material.) If there is no such security property value specified, the default value of "IbmX509" is used to perform the search. Note: A KeyManagerFactory implementation for the "IbmX509" algorithm is supplied by the IBMJSSE2 provider. The KeyManager it specifies is a javax.net.ssl.X509KeyManager implementation. Similarly, the TrustManager implementation chosen is determined by first examining the security property:
ssl.TrustManagerFactory.algorithm
If such a property value is specified, a TrustManagerFactory implementation for the specified algorithm is searched for. The implementation from the first provider that supplies an implementation is used. Its getTrustManagers method is called to determine the TrustManager to supply to the default SSLContext. (Technically, getTrustManagers returns an array of TrustManagers, one TrustManager for each type of trust material.) If there is no such security property value specified, the default value of "PKIX" is used to perform the search. Note: A TrustManagerFactory implementation for the "PKIX" algorithm is supplied by the IBMJSSE2 provider. The TrustManager it specifies is a javax.net.ssl.X509TrustManager implementation. Important Note: This section describes the current JSSE reference implementation behavior. The system properties described in this section are not guaranteed to continue to have the same names and types (system or security) or even to exist at all in future releases. They also might not be examined and used by any other JSSE implementations. If they are examined by an implementation, that implementation should handle them in the same manner as the JSSE reference implementation does, as described herein.
Customizing the Encryption Algorithm Providers
As of the SDK 5 release, the IBMJSSE2 provider by default uses the IBMJCE implementation for all its cryptographic needs. You can use another implementation from the IBM JCE family of providers by registering them before the IBMJCE provider. The standard JCA mechanism can be used to configure providers, either statically via the security properties file
<java-home>/lib/security/java.security
or dynamically via the addProvider or insertProviderAt method in the java.security.Security class. (See The Installation Directory <java-home> for information about what <java-home> refers to.) Note for People Implementing Providers
The transformation strings used when IBMJSSE2 calls Cipher.getInstance() are "RSA/SSL/PKCS1Padding", "RC4", "RC2/CBC/NoPadding", "DES/CBC/NoPadding", "AES/CBC/NoPadding" and "DESede/CBC/NoPadding ". For further information on the Cipher class and transformation strings see the JCE Reference Guide.
Use of JCE
The Java Cryptography Extension (JCE) is a set of packages that provides a framework and implementations for encryption, key generation and key agreement, and Message Authentication Code (MAC) algorithms. The IBMJSSE2 provider only is supported using the IBM JCE software and hardware providers. In SDK 1.4.2, the IBMJSSE2 provider supported PKCS#11 through the IBMPKCS11Impl provider. This allowed the IBMJSSE2 provider to be able to use hardware cryptographic accelerators for significant performance improvements and to use Smartcards as keystores for greater flexibility in key and trust management. In order to be compatible with Sun's PKCS#11 support, a configuration file will now be required, even for code which ran successfully on SDK 1.4.2. This configuration file is specific to each hardware device and JSSE. See the IBMPKCS11Impl Provider for the sample configuration files.
Hardware Accelerators
Use of hardware cryptographic accelerators is automatic if JCE has been configured to use the IBM PKCS11Impl provider, which in turn has been configured with the proper configuration file to use the underlying accelerator hardware. The provider must be configured before any other JCE/JCA providers in the provider list. See the IBMPKCS11Impl Provider for details on how to configure the IBMPKCS11Impl provider. Configuring JSSE to use Smartcards as Keystores and Trust Stores
Support for the IBMPKCS11Impl provider also enables access to Smartcards as a keystore. See the Customization section for details on how to configure the type and location of the keystores to be used by JSSE. To use a Smartcard as a keystore or trust store, set the javax.net.ssl.keyStoreType and javax.net.ssl.trustStoreType system properties, respectively, to "PKCS11IMPLKS", and set the javax.net.ssl.keyStore and javax.net.ssl.trustStore system properties, respectively, to NONE. To specify the use of a specific provider, use the javax.net.ssl.keyStoreProvider and javax.net.ssl.trustStoreProvider system properties (e.g., "IBMPKCS11Impl-joe"). By using these properties, you can configure an application that previously depended on these properties to access a file-based keystore to use a Smartcard keystore with no changes to the application. Some applications request the use of keystores programmatically. These applications can continue to use the existing APIs to instantiate a Keystore and pass it to its key manager and trust manager. If the Keystore instance refers to a PKCS11IMPLKS keystore backed by a Smartcard, then the JSSE application will have access to the keys on the Smartcard.
The PKCS11Impl provider must be configured with the proper configuration file specific to the hardware cryptographic device and JSSE before any other JCA/JCE providers in the provider list.
Multiple and Dynamic Keystores
Smartcards (and other removable tokens) have additional requirements for an X509KeyManager. Different Smartcards may be present in a Smartcard reader during the lifetime of a Java application and they may protected using different passwords. The pre-SDK 5 APIs and the IbmX509 key manager do not accomodate these requirements well. As a result, in SDK 5, new APIs were introduced and a new X509KeyManager implementation was added to the IBMJSSE2 provider.
The java.security.KeyStore.Builder class abstracts the construction and initialization of a KeyStore object. It supports the use of CallbackHandlers for password prompting and can be subclassed to support additional features as desired by an application. For example, it is possible to implement a Builder that allows individual KeyStore entries to be protected with different passwords. The javax.net.ssl.KeyStoreBuilderParameters class then can be used to initialize a KeyManagerFactory using one or more of these Builder objects.
A new X509KeyManager implementation in the IBMJSSE2 provider called "NewIbmX509" supports these parameters. If multiple certificates are available, it also makes the effort to pick a certificate with the appropriate key usage and prefers valid to expired certificates
Here is an example of how to tell JSSE to use both a IBMPKCS11ImplKS keystore (which might in turn use a Smartcard) and a PKCS#12 file-based keystore. import javax.net.ssl.*;
import java.security.KeyStore.*;
...
// Specify keystore builder parameters for PKCSIMPLKS keystores
Builder scBuilder = Builder.newInstance("PKCS11IMPLKS", null,
new CallbackHandlerProtection(myGuiCallbackHandler));
// Specify keystore builder parameters for a specific PKCS#12 keystore
Builder fsBuilder = Builder.newInstance("PKCS12", null,
new File(pkcsFileName), new PasswordProtection(pkcsKsPassword));
// Wrap them as key manager parameters
ManagerFactoryParameters ksParams =
new KeyStoreBuilderParameters(
Arrays.asList(new Builder[] { scBuilder, fsBuilder }));
// Create KeyManagerFactory
KeyManagerFactory factory = KeyManagerFactory.getInstance("NewIbmX509");
// Pass builder parameters to factory
factory.init(ksParams);
// Use factory
SSLContext ctx = SSLContext.getInstance("SSL_TLS");
ctx.init(factory.getKeyManagers(), null, null);
In SDK 5, the IBMJSSE2 provider has support for Kerberos cipher suites, as described in RFC 2712. The following cipher suites are supported but not enabled by default.
TLS_KRB5_WITH_RC4_128_SHA
TLS_KRB5_WITH_RC4_128_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_RC4_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
To enable use of these cipher suites, you must do so explicitly. See SSLEngine.setEnabledCipherSuites() and SSLSocket.setEnabledCipherSuites() for more information. As with all other SSL or TLS cipher suites, if a cipher suite is not supported by the peer, then it won't be selected during cipher negotiation. Furthermore, if the application and/or server cannot acquire the necessary Kerberos credentials, then the Kerberos cipher suites also will not be selected. Here is an example of a TLS client that wants to use only the TLS_KRB5_WITH_DES_CBC_SHA cipher suite.
// Create socket
SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(tlsServer, serverPort);
// Enable only one cipher suite
String enabledSuites[] = { "TLS_KRB5_WITH_DES_CBC_SHA" };
sslSocket.setEnabledCipherSuites(enabledSuites);
Kerberos Requirements
You must have the Kerberos infrastructure set up in your deployment environment before you can use the Kerberos cipher suites with JSSE. In particular, both the TLS client and server must have accounts set up with the Kerberos Key Distribution Center (KDC). At runtime, if one or more of the Kerberos cipher suites have been enabled, the TLS client and server will acquire their Kerberos credentials associated with their respective account from the KDC. For example, a TLS server running on the machine mach1.imc.org in the Kerberos realm IMC.ORG must have an account with the name host/mach1.imc.org@IMC.ORG and be configured to use the KDC for IMC.ORG. See the Kerberos Requirements document for information about using Kerberos with SDK. An application can acquire its Kerberos credentials by using the Java Authentication and Authorization Service (JAAS) and a Kerberos login module. SDK 5 Development Kit comes with a Kerberos login module. You can use the Kerberos cipher suites with JSSE with, or without JAAS programming, similar to how you can use the Java Generic Security Services (Java GSS) with, or without JAAS programming.
To use it without JAAS programming, you must use the index names "com.ibm.net.ssl.server" or "other" for the TLS server JAAS configuration entry and "com.ibm.net.ssl.client" or "other" for the TLS client, and set the system property javax.security.auth.useSubjectCredsOnly to false. For example, a TLS server that is not using JAAS programming might have the following JAAS configuration file. com.ibm.net.ssl.server {
com.ibm.security.auth.module.Krb5LoginModule required
principal="host/mach1.imc.org@IMC.ORG"
useKeyTab=true
keyTab=mach1.keytab
storeKey=true;
}; An example of how to Java GSS and Kerberos without JAAS programming is described in the Java GSS Tutorial. You can adapt it to use JSSE by replacing Java GSS calls with JSSE calls.
To use the Kerberos cipher suites with JAAS programming, you can use any index name because your application is responsible for creating the JAAS LoginContext using the index name, and then wrapping the JSSE calls inside of a Subject.doAs() or Subject.doAsPrivileged() call. An example of how to use JAAS with Java GSS and Kerberos is described in the Java GSS Tutorial. You can adapt it to use JSSE by replacing Java GSS calls with JSSE calls.
If you have trouble using or configuring the JSSE application to use Kerberos, see the Troubleshooting section of the Java GSS Tutorial.
Peer Identity Information
To determine the identity of the peer of an SSL connection, use the getPeerPrincipal() method in the following classes: javax.net.ssl.SSLSession, javax.net.ssl.HttpsURLConnection, and javax.net.HandshakeCompletedEvent. Similarly, to get the identity that was sent to the peer (to identify the local entity), use getLocalPrincipal() in these classes. For X509-based cipher suites, these methods will return an instance of javax.security.auth.x500.X500Principal; for Kerberos cipher suites, these methods will return an instance of javax.security.auth.kerberos.KerberosPrincipal. Prior to SDK 5, JSSE applications used getPeerCertificates() and similar methods in javax.net.ssl.SSLSession, javax.net.ssl.HttpsURLConnection, and javax.net.HandshakeCompletedEvent to obtain information about the peer. When the peer does not have any certificates, SSLPeerUnverifiedException is thrown. The behavior of these methods remain unchanged in SDK 5, which means that if the connection was secured using a Kerberos cipher suite, these methods will throw SSLPeerUnverifiedException.
If the application needs to determine only the identity of the peer or identity sent to the peer, it should use the getPeerPrincipal() and getLocalPrincipal() methods, respectively. It should use getPeerCertificates() and getLocalCertificates() only if it needs to examine the contents of those certificates. Furthermore, it must be prepared to handle the case where an authenticated peer might not have any certificate.
Security Manager
When the security manager has been enabled, in addition to the SocketPermissions needed to communicate with the peer, a TLS client application that uses the Kerberos cipher suites also needs the following permission.
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "
initiate");
where serverPrincipal is the Kerberos principal name of the TLS server that the TLS client will be communicating with, such as host/mach1.imc.org@IMC.ORG. A TLS server application needs the following permission.
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "accept
");
where serverPrincipal is the Kerberos principal name of the TLS server, such as host/mach1.imc.org@IMC.ORG. If the server or client needs to contact the KDC (for example, if its credentials are not cached locally), it also needs the following permission.
javax.security.auth.kerberos.ServicePermission(tgtPrincipal, "initiate"
);
where tgtPrincipal is principal name of the KDC, such as krbtgt/IMC.ORG@IMC.ORG.
Additional Keystore Formats (PKCS12)
The PKCS#12 (Personal Information Exchange Syntax Standard) specifies a portable format for storage and/or transport of a user's private keys, certificates, miscellaneous secrets, and other items. The IBMJSSE2 provider uses the Java 2 KeyStore API that supplies a complete implementation of the PKCS12 java.security.KeyStore format for reading and write pkcs12 files. This format is also supported by other toolkits and applications for importing and exporting keys and certificates, such as Netscape/Mozilla, Microsoft's Internet Explorer, and OpenSSL. For example, these implementations can export client certificates and keys into a file using the ".p12" filename extension. With the IBMJSSE2 provider, you can access PKCS12 keys through the KeyStore API with a keystore type of "pkcs12" (or "PKCS12", the name is case-insensitive). In addition, you can list the installed keys and associated certificates using the keytool command with the -storetype option set to pkcs12 or use IKEYMAN. (See Security Tools for information about keytool.)
Running IBMJSSE2 in FIPS mode
The IBMJSSE2 provider can be enabled to run in FIPS mode. In the 1.4.2 sr1a JVM and beyond, there were two JSSE providers which provide FIPS support. The IBMJSSEFIPS provider was the FIPS certified JSSE provider for the original JSSE and has now been removed. Using the IBMJSSE2 provider, it can be enabled to run in FIPS mode with no separate jar required. In order to meet the the requirements set forth in the FIPS publication 140-2, the encryption and signature algorithms utilized by the IBMJSSE2 Provider are isolated into the IBMJCEFIPS provider cryptographic module. When in FIPS mode, the IBMJSSE2 Provider utilizes the cryptographic modules in an approved manner, and therefore IBMJSSE2 complies with the FIPS 140-2 requirements when properly configured. Since cryptographic functionality is performed by IBMJCEFIPS, JSSE changes that affect the IBMJSSE2 provider only and not the cryptography, do not require a new certification.
FIPS requires that the SSL protocol to be TLS. The SSLv3 protocol is not allowed when in FIPS mode. If the client or the server have requested to handshake using the SSLv3 protocol while in FIPS mode, the the handshake will fail. IBMJSSE2 in FIPS mode will only allow the following cipher suites as defined by FIPS:
- SSL_RSA_WITH_AES_128_CBC_SHA
- SSL_RSA_WITH_AES_256_CBC_SHA **
- SSL_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_RSA_WITH_AES_128_CBC_SHA
- SSL_DHE_RSA_WITH_AES_256_CBC_SHA **
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- SSL_DHE_DSS_WITH_AES_128_CBC_SHA
- SSL_DHE_DSS_WITH_AES_256_CBC_SHA **
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- SSL_DH_anon_WITH_AES_128_CBC_SHA
- SSL_DH_anon_WITH_AES_256_CBC_SHA **
- SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
** Note: AES_256 ciphers require the installation of the JCE Unlimited Strength Jurisdiction Policy Files.
Enabling FIPS Mode in the IBMJSSE2 Provider
Enabling FIPS mode in the IBMJSSE2 Provider requires setting the IBMJSSE2 FIPS system property to enable FIPS mode, setting security properties to ensure that all JSSE code uses the IBMJSSE2 provider and therefore runs in FIPS mode, and adding the IBMJCEFIPS cryptographic provider. Detailed instructions follow. No changes to the application to support IBMJSSE2 running in FIPS mode are required. Note that a single JVM cannot be in FIPS mode and have non-FIPS mode JSSE applications executing at the same time. Also note that IBMJSSE2 in FIPS mode and IBMJSSE2 using hardware cryptography is not supported.
- Set the following system property to enable FIPS mode in the IBMJSSE2 Provider:
- com.ibm.jsse2.JSSEFIPS=true
- Set the following security properties to ensure that the IBMJSSE2 Provider is used to handle all JSSE requests.
- ssl.SocketFactory.provider=com.ibm.jsse2.SSLSocketFactoryImpl
- ssl.ServerSocketFactory.provider=com.ibm.jsse2.SSLServerSocketFactoryImpl
- Add the IBMJCEFIPS provider, com.ibm.crypto.fips.provider.IBMJCEFIPS, to the provider list before the IBMJCE provider. Do not remove the IBMJCE provider. The IBMJCE provider is still required for KeyStore support.
Troubleshooting
Configuration Problems
CertificateException: (while handshaking)
Problem: When negotiating an SSL connection, the client or server throws a CertificateException.
Cause 1: This is generally caused by the remote side sending a certificate that is unknown to the local side.
Solution 1: The best way to debug this type of problem is to turn on debugging (see Debugging Utilities) and watch as certificates are loaded and when certificates are received via the network connection. Most likely, the received certificate is unknown to the trust mechanism because the wrong trust file was loaded. Refer the following sections for more information:
Cause 2: The system clock is not set correctly.
Solution 2: If the clock is not set correctly, the perceived time may be outside the validity period on one of the certificates, and unless the certificate can be replaced with a valid one from a truststore, the system must assume that the certificate is invalid, and therefore throw the exception.
Runtime Exception: SSL Service Not Available
Problem: When running a program that uses JSSE, an exception occurs indicating that an SSL service is not available. For example, an exception similar to one of the following occurs: Exception in thread "main" java.net.SocketException: no SSL
Server Sockets
Exception in thread "main": SSL
implementation not available
Cause: There was a problem with SSLContext initialization, for example due to an incorrect password on a keystore or a corrupted keystore. (Note: A JDK vendor once shipped a keystore in an unknown format, and that caused this type of error.) Also verify that the JSSE provider specified is in the provider list.
Solution: Check initialization parameters. Ensure any keystores specified are valid and that the passwords specified are correct. (One way you can check these things is by trying to use the keytool to examine the keystore(s) and the relevant contents.)
Exception, "No available certificate corresponding to the SSL cipher suites which are enabled"
Problem: When I try to run a simple SSL Server program, the following exception is thrown:
Exception in thread "main" javax.net.ssl.SSLException: No available
certificate corresponding to the SSL cipher suites which are enabled...
Cause: Various cipher suites require certain types of key material. For example, if an RSA cipher suite is enabled, an RSA keyEntry must be available in the keystore. If no such key is available, this cipher suite cannot be used. If there are no available key entries for all of the cipher suites enabled, this exception is thrown.
Solution: Create key entries for the various cipher suite types, or use an anonymous suite, which will require your own trustManager. (Be aware that anonymous ciphersuites are inherently dangerous because they are vulnerable to "man-in-the-middle" attacks, see RFC 2246.) Refer to the following sections to learn how to pass the correct keystore and certificates:
Runtime Exception: No Cipher Suites in Common
Problem 1: When handshaking, the client and/or server throw this exception.
Cause 1: Both sides of an SSL connection must agree on a common ciphersuite. If the intersection of the client's ciphersuite set with the server's ciphersuite set is empty, then you will see this exception.
Solution 1: Configure the enabled cipher suites to include common ciphersuites, and be sure to provide an appropriate keyEntry for asymmetric ciphersuites. (See Exception, "No available certificate..." in this section.)
Problem 2: When using Netscape Navigator or Microsoft Internet Explorer (IE) to access files on a server that only has DSA-based certificates, a runtime exception occurs indicating that there are no cipher suites in common.
Cause 2: By default, keyEntries created with keytool use DSA public keys. If only DSA keyEntries exist in the keystore, only DSA-based ciphersuites can be used. By default, Navigator and IE send only RSA-based ciphersuites. Since the intersection of client and server ciphersuite sets is empty, this exception is thrown.
Solution 2: To interact with Navigator or IE, you should create certificates that use RSA-based keys. To do this, you need to specify the -keyalg RSA option when using keytool. For example: keytool -genkey -alias duke -keystore testkeys -keyalg rsa
Debugging Utilities
IBMJSSE2 provides dynamic debug tracing support. This is similar to the support used for debugging access control failures in the Java 2 platform. The generic Java dynamic debug tracing support is accessed with the system property java.security.debug, while the JSSE-specific dynamic debug tracing support is accessed with the system property javax.net.debug.
Note: The debug utility is not an officially supported feature of JSSE.
To view the options of the JSSE dynamic debug utility, use the following command-line option on the java command: -Djavax.net.debug=help
Note: If you specify the value help with either dynamic debug utility when running a program that does not use any classes that the utility was designed to debug, you will not get the debugging options.
Here is a complete example of how to get a list of the debug options: java -Djavax.net.debug=help MyApp where MyApp is an application that uses some of the JSSE classes. MyApp will not run after the debug help information is printed, as the help code causes the application to exit. Here are the current options: all turn on all debugging
true turn on all debugging - compatibility with IBMJSSE Provider
ssl turn on ssl debugging
The following can be used with ssl:
record enable per-record tracing
handshake print each handshake message
keygen print key generation data
session print session activity
defaultctx print default SSL initialization
sslctx print SSLContext tracing
sessioncache print session cache tracing
keymanager print key manager tracing
trustmanager print trust manager tracing
handshake debugging can be widened with:
data hex dump of each handshake message
verbose verbose handshake message printing
record debugging can be widened with:
plaintext hex dump of record plaintext
packet print raw SSL or TLS packets
The javax.net.debug property value must specify either all, true or ssl, optionally followed by debug specifiers. You can use one or more options. You do not have to have a separator between options, although a separator such as ":" or "," helps readability. It doesn't matter what separators you use, and the ordering of the option keywords is also not important. Examples
- To view all debugging messages:
java -Djavax.net.debug=all MyApp
- To view the hexadecimal dumps of each handshake message, you can type the following, where the colons are optional:
java -Djavax.net.debug=ssl:handshake:data MyApp
- To view the hexadecimal dumps of each handshake message, and to print trust manager tracing, you can type the following, where the commas are optional:
java -Djavax.net.debug=SSL,handshake,data,trustmanager MyApp
Code Examples
The sections below describe the following code examples: SSL Server using Hardware Cryptography through a IBMPKCS11Impl provider
This example shows the server side of a secure socket where the key required by the server is in a hardware cryptography IBMPKCS11Impl type keystore. Using hardware cryptography requires a configuration file that is specific for the hardware crypto card being used. See the IBM PKCS11 Implementaiton Provider for the JSSE configuration files for the different cards. The IBM PKCS11 Implementation Provider also provides details for the setup and creation of the hardware key. Set up to use the IBMPKCS11Impl provider using the configuration file and then add to the Java Provider List. The creation of the key on the hardware cryptography card is not shown.
//***************************************************************************
// Substitute actual hardware and configuration information
String password = "12345678";
String dlllocation = "/usr/lib/pkcs11/PKCS11_API.so";
String slotnumber = 0;
String configname = "/home/test/cfg/4960.cfg";
//*****************************************************************************
// Set up Crypto Card hardware provider.
com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl p1 = new com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl(configname);
// Must add the hardware crypto provider before IBMJCE in the Java Provider List
// but after the Sun provider on Solaris and HP systems.
Security.insertProviderAt(p1,2);
// Add the IBMJSSE2 Provider to the Java Provider list
Security.addProvider(new com.ibm.jsse2.IBMJSSEProvider2());
// Login to the card
char [] passwd = new char[password.length()];
password.getChars(0,password.length(),passwd,0);
NullPrompter np = new NullPrompter(dlllocation + ":" + slotnumber,passwd);
p1.login(null,np);
// Get a keystore of type PKCS11IMPLKS. The name of keystore
// is not revelant for a PKCS11IMPLKS keystore.
KeyStore ks = KeyStore.getInstance("PKCS11IMPLKS");
ks.load(null, null);
// Create a KeyManagerFactory that implements the X.509 key management
// algorithm using the IBMJSSE2 provider.
KeyManagerFactory kmf = KeyManagerFactory.getInstance("IbmX509","IBMJSSE2");
// already logged into card. Password not required.
kmf.init(ks, null);
// Initialize the SSLContext with the KeyManagerFactory and the default
// TrustManager. Because there is no client authentication, no trusted
// certificates are required. SSL_TLS will allow the server to handshake
// using SSLv3 or TLSv1 protocol and will accept a v2 hello.
sslContext = SSLContext.getInstance("SSL_TLS","IBMJSSE2");
sslContext.init(kmf.getKeyManagers(), null, null);
// Create an SSL socket over port 8050
SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
SSLServerSocket ssl_server_sock = (SSLServerSocket)factory.createServerSocket(
8050);
// rest not shown
SSL Server using Hardware Accelerator through a IBMPKCS11Impl provider
This example shows the server side of a secure socket using the hardware accelerator card to provide bulk encryption, if the card supports it. The key and trusted certificates will come from a JKS keystore. The server will request client authentication. See the IBM PKCS11 Implementation Provider for details on using the IBMPKCS11Impl provider and obtaining the proper configuration file for your specific hardware cryptographic device.
Set up to use the IBMPKCS11Impl provider using the configuration file and then add to the Java Provider List. The creation of the key on the hardware cryptography card is not shown.
//***************************************************************************
// Substitute actual hardware and configuration information
String password = "12345678";
String dlllocation = "/usr/lib/pkcs11/PKCS11_API.so";
String slotnumber = 0;
String configname = "/home/test/cfg/4960.cfg";
//*****************************************************************************
// Set up Crypto Card hardware provider.
com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl p1 = new com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl(configname);
// Must add the hardware crypto provider before IBMJCE in the Java Provider List
// but after the Sun provider on Solaris and HP systems.
Security.insertProviderAt(p1,2);
// Add the IBMJSSE2 Provider to the Java Provider list
Security.addProvider(new com.ibm.jsse2.IBMJSSEProvider2());
// Login to the card
char [] passwd = new char[password.length()];
password.getChars(0,password.length(),passwd,0);
NullPrompter np = new NullPrompter(dlllocation + ":" + slotnumber,passwd);
p1.login(null,np);
// Get a keystore of type JKS.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load("testkeys","passphrase".toCharArray());
// Create a KeyManagerFactory that implements the X.509 key management
// algorithm using the IBMJSSE2 provider.
KeyManagerFactory kmf = KeyManagerFactory.getInstance("IbmX509","IBMJSSE2");
// Load the keystore with the appropriate password
kmf.init(ks, "passphrase".toCharArray());
// Create a TrustManagerFactory that implements the X.509 key
// management algorithm using the IBMJSSE2 provider.
TrustManagerFactory tmf = TrustManagerFactory.getInstance("IbmX509","IBMJSSE2");
// Because client authentication will be requested,
// the server must be able to trust the client.
tmf.init(ks);
// Initialize the SSLContext with the KeyManagerFactory and the
// TrustManagerFactory. "SSL" will allow the server to handshake
// using "SSLv3" and will accept a v2 hello.
sslContext = SSLContext.getInstance("SSL","IBMJSSE2");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// Create an SSL socket over port 8050
SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
SSLServerSocket ssl_server_sock = (SSLServerSocket)factory.createServerSocket(8050);
// Require client authentication
ssl_server_sock.setNeedClientAuth(true);
// rest not shown
The protocol name parameter passed to the getInstance method of SSLContext supports a named secure socket protocol. The table below lists some common standard protocol names.
| Protocol |
Comment |
| SSL |
SSL version 3 protocol. Will accept SSLv3 hello encapsulated in a SSLv2 format hello. |
| SSLv3 |
SSL version 3 protocol. |
| TLS |
TLS version 1 protocol (defined in RFC 2246) Will accept TLSv1 hello encapsulated in an SSLv2 format hello. |
| TLSv1 |
TLS version 1 protocol (defined in RFC 2246) Will accept SSLv3 or TLSv1 hello encapsulated in an SSLv2 format hello. |
| SSL_TLS |
Enables all SSL and TLS protocols. Will accept SSLv3 or TLSv1 hello encapsulated in an SSLv2 format hello. |
The keyType parameter passed to the chooseClientAlias, chooseServerAlias, getClientAliases, and getServerAliases methods of X509KeyManager specify the public key type(s). Each row of the table below lists the standard name that should be used for keyType, given the specified certificate type.
| Name |
Certificate Type |
Corresponds to (RFC 2246) |
| RSA |
RSA |
rsa_sign(1) |
| DSA |
DSA |
dss_sign(2) |
| DH_RSA |
Diffie-Hellman with RSA signature |
rsa_fixed_dh(3) |
| DH_DSA |
Diffie-Hellman with DSA signature |
dss_fixed_dh(4) |
The protocols parameter passed to the setEnabledProtocols method of SSLSocket specifies the protocol versions to be enabled for use on the connection. The table below lists the standard names that can be passed to setEnabledProtocols or that may be returned by the SSLSocket getSupportedProtocols and getEnabledProtocols methods.
| Name |
Protocol |
| SSL |
SSL version 3 protocol. Will accept SSLv3 hello encapsulated in a SSLv2 format hello. |
| SSLv3 |
SSL version 3 protocol. |
| TLS |
TLS version 1 protocol (defined in RFC 2246) Will accept TLSv1 hello encapsulated in an SSLv2 format hello. |
| TLSv1 |
TLS version 1 protocol (defined in RFC 2246) |
| SSL_TLS |
Enables all SSL and TLS protocols. Will accept SSLv3 or TLSv1 hello encapsulated in an SSLv2 format hello. |
The authType parameter passed to the checkClientTrusted and checkServerTrusted methods of X509TrustManager indicates the authentication type. The table below specifies what standard names should be used for the client or server certificate chains.
| Client or Server Certificate Chain |
Authentication Type Standard Name |
| Client |
Determined by the actual certificate used. For instance, if RSAPublicKey is used, the authType should be "RSA". |
| Server |
The key exchange algorithm portion of the cipher suites represented as a String, such as "RSA" or "DHE_DSS". Note: For some exportable cipher suites, the key exchange algorithm is determined at run time during the handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5, the authType should be "RSA_EXPORT" when an ephemeral RSA key is used for the key exchange, and "RSA " when the key from the server certificate is used. Or it can take the value "UNKNOWN ". |
The following table lists the standard cipher suite names.
Cipher Suite
Cipher Suite name may begin with "SSL" or "TLS". |
Releases Supported In |
Original JSSE
|
1.4.2 |
5 |
SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA |
|
|
|
SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA |
|
|
|
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA |
X |
X |
X |
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA |
X |
X |
X |
SSL_DHE_DSS_WITH_DES_CBC_SHA |
X |
X |
X |
SSL_DHE_DSS_WITH_RC4_128_SHA |
|
X |
X |
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA |
X |
X |
X |
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA |
X |
X |
X |
SSL_DHE_RSA_WITH_DES_CBC_SHA |
X |
X |
X |
SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA |
X |
X |
X |
SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA |
X |
X |
X |
SSL_DH_DSS_WITH_DES_CBC_SHA |
X |
X |
X |
SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA |
|
|
|
SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA |
|
|
|
SSL_DH_RSA_WITH_DES_CBC_SHA |
|
|
|
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA * |
X |
X |
X |
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 * |
X |
X |
X |
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA * |
X |
X |
X |
SSL_DH_anon_WITH_DES_CBC_SHA * |
X |
X |
X |
SSL_DH_anon_WITH_RC4_128_MD5 * |
X |
X |
X |
SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA |
|
|
|
SSL_FORTEZZA_DMS_WITH_NULL_SHA |
|
|
|
SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA |
|
|
|
SSL_RSA_EXPORT1024_WITH_RC4_56_SHA |
|
|
|
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA |
X |
X |
X |
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 |
X |
X |
X |
SSL_RSA_EXPORT_WITH_RC4_40_MD5 |
X |
X |
X |
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA |
X |
X |
X |
SSL_RSA_FIPS_WITH_DES_CBC_SHA |
X |
X |
X |
SSL_RSA_WITH_3DES_EDE_CBC_SHA |
X |
X |
X |
SSL_RSA_WITH_DES_CBC_SHA |
X |
X |
X |
SSL_RSA_WITH_IDEA_CBC_SHA |
|
|
|
SSL_RSA_WITH_NULL_MD5 |
X |
X |
X |
SSL_RSA_WITH_NULL_SHA |
X |
X |
X |
SSL_RSA_WITH_RC4_128_MD5 |
X |
X |
X |
SSL_RSA_WITH_RC4_128_SHA |
X |
X |
X |
SSL_DHE_DSS_WITH_AES_128_CBC_SHA |
|
X |
X |
SSL_DHE_DSS_WITH_AES_256_CBC_SHA ** |
|
X |
X |
SSL_DHE_RSA_WITH_AES_128_CBC_SHA |
|
X |
X |
SSL_DHE_RSA_WITH_AES_256_CBC_SHA ** |
|
X |
X |
SSL_DH_anon_WITH_AES_128_CBC_SHA * |
|
X |
X |
SSL_DH_anon_WITH_AES_256_CBC_SHA * ** |
|
X |
X |
SSL_KRB5_EXPORT_WITH_DES_CBC_40_MD5 |
|
|
X |
SSL_KRB5_EXPORT_WITH_DES_CBC_40_SHA |
|
|
X |
SSL_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 |
|
|
|
SSL_KRB5_EXPORT_WITH_RC2_CBC_40_SHA |
|
|
|
SSL_KRB5_EXPORT_WITH_RC4_40_MD5 |
|
|
X |
SSL_KRB5_EXPORT_WITH_RC4_40_SHA |
|
|
X |
SSL_KRB5_WITH_3DES_EDE_CBC_MD5 |
|
|
X |
SSL_KRB5_WITH_3DES_EDE_CBC_SHA |
|
|
X |
SSL_KRB5_WITH_DES_CBC_MD5 |
|
|
X |
SSL_KRB5_WITH_DES_CBC_SHA |
|
|
X |
SSL_KRB5_WITH_IDEA_CBC_MD5 |
|
|
|
SSL_KRB5_WITH_IDEA_CBC_SHA |
|
|
|
SSL_KRB5_WITH_RC4_128_MD5 |
|
|
X |
SSL_KRB5_WITH_RC4_128_SHA |
|
|
X |
SSL_RSA_WITH_AES_128_CBC_SHA |
|
X |
X |
SSL_RSA_WITH_AES_256_CBC_SHA ** |
|
X |
X |
*Although anonymous cipher suites are enabled, the IBMJSSE2 TrustManager does not allow anonymous cipher suites. The default implementation can be overridden by providing your own TrustManager that allows anonymous cipher suites. See Accepting Anonymous Cipher Suites for information about creating your own X509TrustManager. **Requires installation of the JCE Unlimited Strength Jurisdiction Policy Files.
JSSE in SDK 5 allows any JSSE provider be used as long as it supports only the following cipher suites.
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA SSL_DHE_DSS_EXPORT_WITH_DES_40_CBC_SHA SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA SSL_DHE_DSS_WITH_AES_128_CBC_SHA SSL_DHE_DSS_WITH_AES_256_CBC_SHA SSL_DHE_DSS_WITH_DES_CBC_SHA SSL_DHE_DSS_WITH_RC4_128_SHA SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_DHE_RSA_EXPORT_WITH_DES_40_CBC_SHA SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA SSL_DHE_RSA_WITH_AES_128_CBC_SHA SSL_DHE_RSA_WITH_AES_256_CBC_SHA SSL_DHE_RSA_WITH_DES_CBC_SHA SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA SSL_DH_ANON_EXPORT_WITH_DES_40_CBC_SHA SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5 SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA SSL_DH_ANON_WITH_AES_128_CBC_SHA SSL_DH_ANON_WITH_AES_256_CBC_SHA SSL_DH_ANON_WITH_DES_CBC_SHA SSL_DH_ANON_WITH_RC4_128_MD5 SSL_DH_ANON_WITH_RC4_MD5 SSL_DH_DSS_EXPORT_WITH_DES_40_CBC_SHA SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA SSL_DH_DSS_WITH_AES_128_CBC_SHA SSL_DH_DSS_WITH_AES_256_CBC_SHA SSL_DH_DSS_WITH_DES_CBC_SHA SSL_DH_RSA_EXPORT_WITH_DES_40_CBC_SHA SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA SSL_DH_RSA_WITH_AES_128_CBC_SHA SSL_DH_RSA_WITH_AES_256_CBC_SHA SSL_DH_RSA_WITH_DES_CBC_SHA SSL_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_RSA_EXPORT_WITH_DES_40_CBC_SHA SSL_RSA_EXPORT_WITH_RC2_40_CBC_MD5 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 SSL_RSA_EXPORT_WITH_RC4_40_MD5 SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA SSL_RSA_FIPS_WITH_DES_CBC_SHA SSL_RSA_WITH_3DES_EDE_CBC_MD5 SSL_RSA_WITH_3DES_EDE_CBC_SHA SSL_RSA_WITH_AES_128_CBC_SHA SSL_RSA_WITH_AES_256_CBC_SHA SSL_RSA_WITH_DES_CBC_MD5 SSL_RSA_WITH_DES_CBC_SHA SSL_RSA_WITH_NULL_MD5 SSL_RSA_WITH_NULL_SHA SSL_RSA_WITH_RC2_CBC_MD5 SSL_RSA_WITH_RC4_128_MD5 SSL_RSA_WITH_RC4_128_SHA SSL_RSA_WITH_RC4_MD5 SSL_RSA_WITH_RC4_SHA SSL_KRB5_EXPORT_WITH_DES_CBC_40_MD5 SSL_KRB5_EXPORT_WITH_DES_CBC_40_SHA SSL_KRB5_EXPORT_WITH_RC4_40_MD5 SSL_KRB5_EXPORT_WITH_RC4_40_SHA SSL_KRB5_WITH_3DES_EDE_CBC_MD5 SSL_KRB5_WITH_3DES_EDE_CBC_SHA SSL_KRB5_WITH_DES_CBC_MD5 SSL_KRB5_WITH_DES_CBC_SHA SSL_KRB5_WITH_RC4_128_MD5 SSL_KRB5_WITH_RC4_128_SHA SSL_CK_RC4_128_WITH_MD5 SSL_CK_RC4_128_EXPORT40_WITH_MD5 SSL_CK_RC2_128_CBC_WITH_MD5 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 SSL_CK_IDEA_128_CBC_WITH_MD5 SSL_CK_DES_64_CBC_WITH_MD5 SSL_CK_DES_192_EDE3_CBC_WITH_MD5
|
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_DSS_EXPORT_WITH_DES_40_CBC_SHA TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLS_DHE_DSS_WITH_AES_128_CBC_SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA TLS_DHE_DSS_WITH_DES_CBC_SHA TLS_DHE_DSS_WITH_RC4_128_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES_40_CBC_SHA TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA TLS_DHE_RSA_WITH_AES_128_CBC_SHA TLS_DHE_RSA_WITH_AES_256_CBC_SHA TLS_DHE_RSA_WITH_DES_CBC_SHA TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA TLS_DH_ANON_EXPORT_WITH_DES_40_CBC_SHA TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5 TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA TLS_DH_ANON_WITH_AES_128_CBC_SHA TLS_DH_ANON_WITH_AES_256_CBC_SHA TLS_DH_ANON_WITH_DES_CBC_SHA TLS_DH_ANON_WITH_RC4_128_MD5 TLS_DH_ANON_WITH_RC4_MD5 TLS_DH_DSS_EXPORT_WITH_DES_40_CBC_SHA TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA TLS_DH_DSS_WITH_AES_128_CBC_SHA TLS_DH_DSS_WITH_AES_256_CBC_SHA TLS_DH_DSS_WITH_DES_CBC_SHA TLS_DH_RSA_EXPORT_WITH_DES_40_CBC_SHA TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA TLS_DH_RSA_WITH_AES_128_CBC_SHA TLS_DH_RSA_WITH_AES_256_CBC_SHA TLS_DH_RSA_WITH_DES_CBC_SHA TLS_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_RSA_EXPORT_WITH_DES_40_CBC_SHA TLS_RSA_EXPORT_WITH_RC2_40_CBC_MD5 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLS_RSA_EXPORT_WITH_RC4_40_MD5 TLS_RSA_FIPS_WITH_3DES_EDE_CBC_SHA TLS_RSA_FIPS_WITH_DES_CBC_SHA TLS_RSA_WITH_3DES_EDE_CBC_MD5 TLS_RSA_WITH_3DES_EDE_CBC_SHA TLS_RSA_WITH_AES_128_CBC_SHA TLS_RSA_WITH_AES_256_CBC_SHA TLS_RSA_WITH_DES_CBC_MD5 TLS_RSA_WITH_DES_CBC_SHA TLS_RSA_WITH_NULL_MD5 TLS_RSA_WITH_NULL_SHA TLS_RSA_WITH_RC2_CBC_MD5 TLS_RSA_WITH_RC4_128_MD5 TLS_RSA_WITH_RC4_128_SHA TLS_RSA_WITH_RC4_MD5 TLS_RSA_WITH_RC4_SHA TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA TLS_KRB5_EXPORT_WITH_RC4_40_MD5 TLS_KRB5_EXPORT_WITH_RC4_40_SHA TLS_KRB5_WITH_3DES_EDE_CBC_MD5 TLS_KRB5_WITH_3DES_EDE_CBC_SHA TLS_KRB5_WITH_DES_CBC_MD5 TLS_KRB5_WITH_DES_CBC_SHA TLS_KRB5_WITH_RC4_128_MD5 TLS_KRB5_WITH_RC4_128_SHA TLS_CK_RC4_128_WITH_MD5 TLS_CK_RC4_128_EXPORT40_WITH_MD5 TLS_CK_RC2_128_CBC_WITH_MD5 TLS_CK_RC2_128_CBC_EXPORT40_WITH_MD5 TLS_CK_IDEA_128_CBC_WITH_MD5 TLS_CK_DES_64_CBC_WITH_MD5 TLS_CK_DES_192_EDE3_CBC_WITH_MD5
|
Notices
This information was developed for products and services offered in the U.S.A. IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to:
- IBM Director of Licensing
IBM Corporation North Castle Drive, Armonk NY 10504-1758 U.S.A.
For license inquiries regarding double-byte (DBCS) information, contact the IBM Intellectual Property Department in your country or send inquiries, in writing, to:
- IBM World Trade Asia Corporation Licensing
2-31 Roppongi 3-chome, Minato-ku Tokyo 106-0032, Japan
The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law:
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the information. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this information at any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you.
Licensees of this program who wish to have information about it for the purpose of enabling (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact:
- JIMMAIL@uk.ibm.com
[Hursley Java Technology Center (JTC) contact]
Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.
The licensed program described in this document and all licensed material available for it are provided by IBM under terms of the IBM Customer Agreement, IBM International Program License Agreement or any equivalent agreement between us.
Any performance data contained herein was determined in a controlled environment. Therefore, the results obtained in other operating environments may vary significantly. Some measurements may have been made on development-level systems and there is no guarantee that these measurements will be the same on generally available systems. Furthermore, some measurement may have been estimated through extrapolation. Actual results may vary. Users of this document should verify the applicable data for their specific environment.
Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products.
Trademarks
IBM is a trademark or registered trademark of International Business Machines Corporation in the United States, or other countries, or both.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
|