Oracle® Containers for J2EE Security Guide 10g (10.1.3.5.0) Part Number E13977-01 |
|
|
View PDF |
This chapter discusses features of Oracle security for clients. These features mainly provide Secure Sockets Layer (SSL) functionality to client HTTP connections in conjunction with functionality of the HTTPClient
package, and support the use of the standard Java Secure Socket Extension (JSSE). In addition, a section is included that documents the HTTP Client's non-SSL authentication features. This chapter may be of interest for any Java application that is to use SSL, where either OC4J is the Web listener (such as in standalone OC4J), or OC4J is behind Oracle HTTP Server. The following topics are included:
Notes:
In addition to JSSE, Oracle Java SSL is also supported, but is deprecated in the OC4J 10.1.3.1 implementation and will be desupported in future releases. We recommend that you use JSSE. As a step in the Oracle Java SSL deprecation, JSSE is the default SSL implementation for HTTPClient
in the OC4J 10.1.3.1 implementation. Aside from the last section on Oracle Java SSL, this chapter emphasizes the use of JSSE.
This chapter assumes that you have already obtained keys and certificates. For general information about configuring OC4J to use the Secure Sockets Layer, see Chapter 15, "SSL Communication with OC4J". You can also refer to that chapter for information about "Requesting Client Authentication".
See Also:
For general information about JSSE:
http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html
This chapter primarily focuses on HTTPS for client security. However, there are several HTTP Client APIs that clients can use for non-SSL authentication. The library can be used to create HTTP requests that include basic, digest, and NT LAN Manager (NTLM) authentication information in the request header. This section includes instructions for using the HTTPClient
package to create these types of requests. For detailed HTTP Client API information, refer to the Oracle Application Server HTTPClient Java API Reference.
The HTTP Client can be used to create an HTTP request to access a server resource that requires basic authentication. The following example demonstrates creating a request and using the addBasicAuthorization
method to include the realm, username, and password with the request.
URL url = new URL("http://localhost:1234"); HTTPConnection client = new HTTPConnection(url); try { client.addBasicAuthorization("realm_name", "user", "password"); HTTPResponse response = client.Get(url.getFile()); //assertEquals(200, response.getStatusCode()); } finally { client.stop(); }
The realm is a server specified string which groups various URLs under a given server together and which is used to select the correct information when a server issues an authentication challenge. The realm must be the empty string (""
) for schemes which don't use a realm.
The HTTP Client can be used to create an HTTP request to access a resource that requires digest authentication. With the digest authentication mechanism, the password that a client presents to authenticate itself is encrypted through the use of an MD5 digest. This is transmitted in the request message. From a user perspective, digest authentication behaves in the same way as basic authentication. The following example demonstrates creating a request and using the addDigestAuthorization
method to include the realm, username, and password with the request.
HTTPConnection client = new HTTPConnection(url); try { client.addDigestAuthorization("ProxyAuthDigestSchemeTestServlet", validUserName,validPassword); HTTPResponse response = client.Get(url.getFile()); // assertEquals(200, response.getStatusCode()); } finally { client.stop(); }
The realm is a server specified string which groups various URLs under a given server together and which is used to select the correct information when a server issues an authentication challenge. The realm must be the empty string (""
) for schemes which don't use a realm.
NTLM is a proprietary challenge/response authentication protocol used by Microsoft browsers, proxies, and servers. A client using NTLM is able to prove its identity to a server without sending a password. NTLM is a connection-oriented protocol. Once the connection is authenticated, no further credentials are required as long as the connection remains open.
In NTLM, the NT Domain name qualifies the username. The account identifier is \
. The NT Domain may be specified in HTTP Client by prefixing the username with the NT Domain name followed by a backslash. For example, for the NT Domain OPERATIONS
and the username jsmith
, the fully qualified username is OPERATIONS\jsmith
.
If no NT Domain is given, the default (if any) is assumed. The default NT Domain is set in the HTTP Client using the system property HTTPClient.ntlm.defaultDomainName
. If the username is given without an NT Domain, and no default NT Domain is defined in HTTP Client, the NTLM-protected server may assume its own default NT Domain.
To connect to an NTLM-protected resource server, add the NTLM credentials to the HTTP Client AuthorizationInfo
credential store. As with basic and digest authentication, HTTP Client will automatically query the credential store, when challenged by an NTLM server. Credentials may be added to the credential store either by using an HTTP Connection instance:
HTTPConnection conn = new HTTPConnection( myHost, myPort ); conn.addNtlmAuthentication( myUsername, myPassword );
Or, directly using the AuthorizationInfo
class:
AuthorizationInfo.addNtlmAuthentication( myHost, myPort, myUsername, myPassword )
The following example demonstrates creating a request and using the addNtlmAuthentication
method to include the username and password with the request.
HTTPConnection conn = new HTTPConnection( myHost, myPort ); conn.addNtlmAuthentication( myUsername, myPassword ); HTTPResponse response = conn.Get( "/index.htm" ); int status = response.getStatusCode(); assertEquals( 200, status );
Note:
A realm, as specified in authentication schemes such as basic authentication, does not apply to NTLM. The NTLM challenge does not have a realm directive. Therefore, all NTLM credentials are assumed to be part of the same empty (""
) realm within HTTP Client.How to Connect to an NTLM-Protected Proxy Server
Proxy servers may also use NTLM for client authentication. However, unlike request-oriented authentication, an NTLM client may only authenticate its connection with the proxy, not the resource server.
To connect to an NTLM-protected proxy server, add the NTLM credentials to the HTTP Client AuthorizationInfo
credential store. As with basic and digest authentication, the HTTP Client automatically queries the credential store when challenged by an NTLM server. Credentials may only be directly added to the credential store using AuthorizationInfo
. For example:
AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername, myPassword)
The following example demonstrates a client that uses NTML to connect to a protected proxy server:
HTTPConnection conn = new HTTPConnection( myHost, myPort ); conn.setCurrentProxy( myProxyHost, myProxyPort ); AuthorizationInfo.addNtlmAuthentication( myProxyHost, myProxyPort, myUsername, myPassword, conn.getContext() ) HTTPResponse response = conn.Get( "/index.htm" ); int status = response.getStatusCode(); assertEquals( 200, status );
HTTPS is vital to securing client/server interactions. For many server applications, HTTPS is handled by the Web server. However, any application that acts as a client, such as a Web application that initiates connections to other Web servers, needs its own HTTPS implementation to make requests and to receive information securely from the server. Java application developers who are familiar with either the HTTPClient
package or the Sun Microsystems java.net
package can easily use HTTPS to secure client interactions with a server.
Oracle client HTTPS functionality is based on the HTTPConnection
class of the HTTPClient
package, which provides a complete HTTP client library. The HTTPConnection
class is used to create new connections that use HTTP, with or without SSL.
Important:
The Oracle implementation ofHTTPClient
has diverged from the original open source version upon which it was based. The Oracle version should be considered as a distinct product. Even though there are still many similarities, the two are not necessarily compatible with each other.See Also:
Documentation for JSSE and the java.net
package:
http://java.sun.com/products/jsse/index.jsp http://java.sun.com/j2se/1.4.2/docs/api/
Oracle Application Server HTTPClient Java API Reference (Javadoc for the HTTPClient
packages)
Oracle client HTTPS extends the HTTPConnection
class of the HTTPClient
package to provide SSL functionality, including cipher suite selection, security credential management with Oracle Wallet Manager, support of security-aware applications, and other features that are described in the following sections. Oracle client HTTPS supports HTTP 1.0 and HTTP 1.1 connections between a client and a server.
HTTPClient
supports two SSL implementations, JSSE and Oracle Java SSL. The latter is deprecated in the OC4J 10.1.3.1 implementation, however, and will be desupported in future releases. We recommend that you use JSSE.
In addition to the functionality included in the HTTPClient
package, Oracle client HTTPS supports the following:
Multiple cryptographic algorithms
Certificate and key management with Oracle Wallet Manager
Limited support for the java.net.URL
framework
In addition, the HTTPClient
package is used to support:
HTTPS tunneling through proxies
HTTP proxy authentication
The following sections describe some of the features:
When using JSSE, you can use a PKCS12 or SSO (auto-login) Oracle wallet with the Oracle JSSE implementation (OraclePKIProvider
), or a JKS-format keystore with the default Sun Microsystems JSSE implementation. (Oracle Java SSL supports only text-format Oracle wallets.)
For either PKCS12 or SSO wallets, credential information is encrypted. The main difference is that with an SSO wallet, you do not have to present a wallet password to open the wallet at time of access.
JKS and PKCS12 are standard formats; SSO wallets are Oracle-proprietary.
See Also:
Oracle Application Server Administrator's Guide (in the chapter for managing wallets and certificates) for details about creating and using PKCS12 and SSO/auto-login wallets
Users can access information regarding established SSL connections using the getSSLSession()
method in the HTTPConnection
class of the Oracle HTTPClient
package. After a connection is established, users can retrieve the cipher suite used for the connection, the peer certificate chain, and other information about the current connection.
The HTTPClient
package provides basic support for the java.net.URL
framework with the HTTPClient.HttpURLConnection
class. However, many of the Oracle client HTTPS features are supported through system properties only.
Features that are supported only through system properties are:
Confidentiality-only option
Server authentication option
Mutual authentication option
Security credential management with Oracle Wallet Manager
Note:
If thejava.net.URL
framework is used, set the java.protocol.handler.pkgs
system property to select the HTTPClient
package as a replacement for the JDK client, as follows:
java.protocol.handler.pkgs=HTTPClient
See Also:
Javadoc for the java.net.URL
class, at:
Before data can flow through an SSL connection, both sides of the connection must negotiate common algorithms to be used for data transmission. A set of such algorithms combined to provide a mix of security features is called a cipher suite. Selecting a particular cipher suite lets the participants in an SSL connection establish the appropriate level for their communications.
In general, you should prefer:
RSA to Diffie-Hellman, because RSA defeats many security attacks
3DES or RC4 128 to other encryption methods, because 3DES and RC4 128 have strong keys
SHA1 digest to MD5, because SHA1 produces a stronger digest
As of the OC4J 10.1.3.1 release, JSSE supports the following cipher suites, listed in default preference order. In this list, "*" indicates the cipher suite is enabled by default, and "**" indicates the cipher suite requires the installation of the JCE Unlimited Strength Jurisdiction Policy Files from Sun Microsystems. Note that with null encryption, SSL is used only for authentication and data integrity purposes.
Note:
HTTPClient
does not provide a way to selectively enable a subset of supported cipher suites.SSL_RSA_WITH_RC4_128_MD5 * SSL_RSA_WITH_RC4_128_SHA * TLS_RSA_WITH_AES_128_CBC_SHA * TLS_DHE_RSA_WITH_AES_128_CBC_SHA * TLS_DHE_DSS_WITH_AES_128_CBC_SHA * SSL_RSA_WITH_3DES_EDE_CBC_SHA * SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA * SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA * SSL_RSA_WITH_DES_CBC_SHA * SSL_DHE_RSA_WITH_DES_CBC_SHA * SSL_DHE_DSS_WITH_DES_CBC_SHA * SSL_RSA_EXPORT_WITH_RC4_40_MD5 * SSL_RSA_EXPORT_WITH_DES40_CBC_SHA * SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA * SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA * TLS_RSA_WITH_AES_256_CBC_SHA ** TLS_DHE_RSA_WITH_AES_256_CBC_SHA ** TLS_DHE_DSS_WITH_AES_256_CBC_SHA ** SSL_RSA_WITH_NULL_MD5 SSL_RSA_WITH_NULL_SHA SSL_DH_anon_WITH_RC4_128_MD5 TLS_DH_anon_WITH_AES_128_CBC_SHA TLS_DH_anon_WITH_AES_256_CBC_SHA ** SSL_DH_anon_WITH_3DES_EDE_CBC_SHA SSL_DH_anon_WITH_DES_CBC_SHA SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
See Also:
For general information about JSSE:
http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html
This section discusses standard Java system properties supported for keystores and truststores. (These properties offer the only way for users of the java.net.URL
framework to set security credential information.) Oracle client HTTPS recognizes the following properties:
Note:
You can set Java system properties on the JVM command line for standalone OC4J, or in a Java property setting for the OC4J instance in theopmn.xml
file in an Oracle Application Server environment. Setting system properties is described in the Oracle Containers for J2EE Configuration and Administration Guide, in the chapter on OC4J runtime configuration.This property specifies the location and name of the keystore file or wallet file to use as the keystore.
This property can be set to indicate the password that is necessary to open the keystore (keystore file or wallet file). For example:
javax.net.ssl.keyStorePassword=welcome1
Important:
Storing the keystore password as a Java system property can result in a security risk in some environments. To avoid this risk, use one of the following alternatives:If mutual authentication is not required for the application, use an SSO wallet, which does not require a password.
If a password is necessary, do not store it in a clear text file. As an alternative, you can load the property dynamically before the HTTPConnection
is started by using the System.setProperty()
method. Unset the property after the handshake is completed.
This property specifies the type of file used for the keystore. With the Oracle JSSE implementation (OraclePKIProvider
), you can specify PKCS12
or SSO
. With the default Sun Microsystems JSSE implementation, you can specify JKS
.
See Also:
The SSL overview in the Oracle Application Server Administrator's Guide for discussion of the PKCS12 type
This property is used similarly to javax.net.ssl.keyStore
, but specifies the location and name of the keystore file or wallet file to use as the truststore (a file that includes the trusted certificate authorities that a client will implicitly accept).
This property is used similarly to javax.net.ssl.keyStorePassword
, but specifies the password that is necessary to open the truststore (keystore file or wallet file).
This section describes Oracle Application Server support for HTTPS client connections using JSSE, covering the following topics:
See Also:
Oracle Application Server Administrator's Guide (in the chapter for managing wallets and certificates) for information about Oracle Wallet Manager and orapki
features for creating and maintaining wallets
For complete information on JSSE:
http://java.sun.com/products/jsse/
Note the following requirements to use JSSE with Oracle client HTTPS:
You must be using Sun Microsystems JDK version 1.2 or higher. (JSSE is included as part of JDK 1.4 or higher.)
The file oraclepki.jar
, located in directory ORACLE_HOME
/network/jlib
, must be in your classpath. (The file jssl-1_1.jar
or jssl-1_2.jar
, used by Oracle Java SSL, is no longer necessary. These files are incompatible with JSSE and are no longer included with your installation.)
Oracle Application Server supports HTTPS client connections using JSSE. A client can configure HTTPClient
to use JSSE as the underlying SSL provider as follows:
Create a truststore using the Sun Microsystems keytool
.
See Also:
For details on using the keytool
:
http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html
Set the truststore property. A client wishing to use JSSE must specify the client truststore location through the javax.net.ssl.trustStore
property. The client is not required to set the javax.net.ssl.keyStore
property.
Obtain the JSSE SSL socket factory (javax.net.ssl.SSLSocketFactory
instance) by calling the static SSLSocketFactory.getDefault()
method.
Create an HTTPClient
connection (HTTPConnection
instance).
Configure the HTTPClient
connection to use the JSSE implementation of SSL. HTTPClient
can be configured to use JSSE in either of the following ways:
(For each connection) The client calls the following method on the HTTPConnection
instance, specifying the JSSE SSL socket factory retrieved by the getDefault()
method in step 3:
void setSSLSocketFactory(SSLSocketFactory factory)
In this case, the SSL socket factory is set for only this connection instance. Example 16-1 below demonstrates this technique.
(Entire VM) The client calls the following static method on the HTTPConnection
class:
void HttpConnection.setDefaultSSLSocketFactory(SSLSocketFactory factory)
In this case, the SSL socket factory is set for all connection instances in the Java VM, until the method is called again with a different setting. This method must be called before instantiating any HTTPConnection
instances that are to be affected.
There must be a call to the HTTPConnection
class connect()
method before sending any HTTPS data. This allows the connection to verify the SSL handshaking that must occur between client and server before any data can be encrypted and sent. In the Oracle implementation, this method is called implicitly during calls to HTTP methods, such as the HTTPConnection
class Get()
method. In addition, an explicit call to the connect()
method is useful when the calling application requires SSL session information before sending data. Also see "Verifying Additional Connection Information".
Use the HTTPConnection
instance normally. At this point, the client is set up to use HTTPClient
with JSSE. There is no additional configuration necessary and basic usage is the same.
Example 16-1 Using JSSE with HTTPClient
public void obtainHTTPSConnectionUsingJSSE() throws Exception { // set the truststore to the location of the client's truststore file // this value specifies the certificate authorities the client accepts System.setProperty("javax.net.ssl.trustStore", KEYSTORE_FILE); // creates the HTTPS URL URL testURL = new URL("https://" + HOSTNAME + ":" + HTTPS_PORTNUM); // call SSLSocketFactory.getDefault() to obtain the default JSSE implementation // of an SSLSocketFactory SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); HTTPConnection connection = new HTTPConnection(testURL); // configure HTTPClient to use JSSE as the underlying // SSL provider connection.setSSLSocketFactory(socketFactory); // call connect to setup SSL handshake try { connection.connect(); } catch (IOException e) { e.printStackTrace(); } HTTPResponse response = connection.Get("/index.html"); }
Notes:
If no SSL socket factory is specified, JSSE would be used anyway, by default, if Oracle Java SSL is not specified as preferred or if Oracle Java SSL classes are not found in the application classpath. If no SSL socket factory is specified and Oracle Java SSL is specified as preferred, and Oracle Java SSL classes are found in the classpath, then Oracle Java SSL is used by default. Also see "Specifying Oracle Java SSL as the SSL Implementation for HTTPClient".
The JSSE SSL implementation is not thread-safe.
Although SSL verifies that the certificate chain presented by the server is valid and contains at least one certificate trusted by the client, that does not prevent impersonation by malicious third parties. An HTTPS standard that addresses this problem requires that HTTPS servers have certificates issued to their host name. Then it is the responsibility of the client to perform this validation after the SSL connection is established.
A host name verifier (javax.net.ssl.HostnameVerifier
implementation) is used by HTTPClient
to verify that the host name in the SSL certificate matches the host name of the URI used to access the protected server. This helps detect "man-in-the-middle" attacks. HTTPClient
invokes the HostnameVerifier
instance immediately after establishing an SSL session, throwing a javax.net.ssl.SSLPeerUnverifiedException
if a host name mismatch is detected.
Important:
You can provide your ownHostnameVerifier
implementation, or use one provided by Oracle (as described below). The implementation must have a no-argument constructor.See Also:
Javadoc for javax.net.ssl.HostnameVerifier
, available through:
http://java.sun.com/j2se/1.4.2/docs/api/
The section discusses how to enable and use this feature, covering the following topics:
Without either the system property setting or the programmatic setting described below, host name verification will not be performed.
To enable host name verification without having to alter your code, set the system property HTTPClient.defaultHostnameVerifier
to the fully-qualified class name of a host name verifier implementation in the classpath.
The setting must specify the name of an appropriate class (a javax.net.ssl.HostnameVerifier
implementation with a no-argument constructor).
You can use the following methods of the HTTPConnection
class to enable host name verification programmatically, by specifying the javax.net.ssl.HostnameVerifier
instance to use for verification:
static HostnameVerifier setDefaultHostnameVerifier (HostnameVerifier defaultHostnameVerifier)
Use this static method to assign the specified HostnameVerifier
instance as the JVM default. This method returns the previously set default host name verifier, or null
if host name verification was previously disabled by default.
HostnameVerifier setHostnameVerifier (HostnameVerifier hostnameVerifier)
Use this instance method to override the default host name verifier and assign the specified HostnameVerifier
instance for use by the connection. You can also specify null
, in order to disable host name verification for the connection.
This method returns the previous host name verifier for the connection, or null
if host name verification was previously disabled for the connection.
Oracle supplies the host name verifier implementation StandardHostnameVerifier
, in the HTTPClient
package.
StandardHostnameVerifier
implements standard host name matching rules for site identity checking, providing the following features:
It verifies the SSL session host name by checking whether the given host name is the same as the common name (CN) of the distinguished name (DN) from the first certificate in the SSL certificate chain. The comparison is not case-sensitive.
If wildcard matching is enabled, it will recognize and match the given host name with a wildcard CN in the SSL certificate (for example, *.oracle.com
), if present.
StandardHostnameVerifier
has the following methods:
boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)
Specify whether to recognize wildcard CNs. This method returns the previously set value.
boolean isRecognizeWildcardCNs()
This method tells you whether wildcard CNs are recognized.
boolean verify(java.lang.String hostname, javax.net.ssl.SSLSession sslSession)
Call this method to verify that the host name is an acceptable match with the authentication scheme of the server. (This is standard functionality specified in the javax.net.ssl.HostnameVerifier
interface.)
You can specify StandardHostnameVerifier
as your host name verifier either programmatically or through the system property setting, as discussed previously. To set it as the default host name verifier, for example, use the following system property setting:
HTTPClient.defaultHostnameVerifier=HTTPClient.StandardHostnameVerifier;
Further validation (beyond host name verification) may be performed using any data found in the javax.net.ssl.SSLSession
object returned from the HTTPConnection
class getSSLSession()
method, after the HTTPConnection
class connect()
is called.
To perform this validation, establish a connection to the server without transferring any data, as follows:
httpsConnection.connect();
After the connection is established, the connection information, in this example the server certificate chain, is obtained as follows:
peerCerts = (httpsConnection.getSSLSession()).getPeerCertificateChain();
Finally the server certificate common name is obtained as follows.
String peerCertDN = peerCerts[0].getSubjectDN().getName(); peerCertDN = peerCertDN.toLowerCase();
(The user's certificate is first in the array; the root CA's certificate is last.)
If the certificate name is not the same as the host name used to connect to the server, then the connection is aborted as follows:
if(peerCertDN.lastIndexOf("cn="+ hostname) == -1) { System.out.println("Certificate for " + hostname + " is issued to " + peerCertDN); System.out.println("Aborting connection"); System.exit(-1); }
Note:
The preferred mechanism is to use the host name verification facility described in the preceding sections.As noted earlier, in the OC4J 10.1.3.1 implementation and beyond, we recommend that you use JSSE rather than Oracle Java SSL. The latter is deprecated in the 10.1.3.1 implementation and will be desupported in future releases. This section discusses how to modify your client code to use JSSE instead of Oracle Java SSL for your SSL functionality.
This section provides code samples to show the steps for creating a new SSL socket factory using JSSE, compared to equivalent code you would have used previously for Oracle Java SSL. The java.security.Keystore
class and various javax.net.ssl
classes are used to open the keystore or wallet and apply Oracle-specific security policies for verifying peer certificates.
See Also:
Javadoc for Keystore
and the javax.net.ssl
classes, available through:
http://java.sun.com/j2se/1.4.2/docs/api/
Here are the steps, with explanations and comparisons:
Register the SSL provider. This step is not necessary if providers are set statically in the jre/lib/security/java.security
properties file for your JDK.
Old code for Oracle Java SSL: not applicable
New code for JSSE:
Security.insertProviderAt(new oracle.security.ssl.OraclePKIProvider(), 1);
The static insertProviderAt()
method of the java.security.Security
class adds a new provider, at a specified preference position. The position refers to the preference order in which providers are searched for requested algorithms, with 1 being most preferred. Use OraclePKIProvider
for enforcement of Oracle security policies. Once you set the provider, you can use standard JSSE classes for your SSL functionality.
Load your keystore, wallet, or trusted certificates.
Old code for Oracle Java SSL:
OracleSSLCredential cred = new OracleSSLCredential(); cred.loadWallet("walletpath", "password");
New code for JSSE:
KeyStore myWallet = KeyStore.getInstance("keystoretype","OraclePKI"); FileInputStream istr = new FileInputStream("pathtowallet"); myWallet.load(istr, password);
The static getInstance()
method of the Keystore
class creates a keystore object for the specified keystore type from the specified provider. Use OraclePKI
as the provider.
In this sample: keystoretype
is PKCS12
or SSO
; pathtowallet
is the path and file name of the keystore or wallet file; and password
is a char[]
array for the password, or null
if you use an SSO wallet.
Note that the OracleSSLCredential
class, used for Oracle Java SSL, is not used for JSSE.
Create the SSL socket factory.
Old code for Oracle Java SSL:
OracleSSLSocketFactory socketFactory = new OracleSSLSocketFactoryImpl(); SocketFactory.setSSLCredentials(cred);
New code for JSSE:
TrustManagerFactory tmf = TrustManagerFactory.getInstance("OracleX509");
tmf.init(trustCerts);
TrustManager[] tmA = tmf.getTrustManagers();
KeyManagerFactory kmf = KeyManagerFactory.getInstance("OracleX509");
kmf.init(trustCerts, password);
KeyManager[] kmA = kmf.getKeyManagers();
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(kmA, tmA, null);
SSLSocketFactory factory = ctx.getSocketFactory();
Create and set trust managers so the SSL connection can verify the peer certificate chain. Create and set key managers so the SSL connection can access the user certificate and private key. Then use key managers and trust managers to configure the SSL context, which is used to create new SSL socket factories. Once an SSLSocketFactory
instance is created, you can use it to create SSL sockets.
Note the following additional changes between Oracle Java SSL and JSSE that may affect your application:
There is a different signature for the createSocket()
method of the SSL socket factory. (This is an OracleSSLSocketFactory
instance for Oracle Java SSL, and an SSLSocketFactory
instance for JSSE.) Note, however, that users of HTTPClient
are not required to call createSocket()
directly.
Old signature for Oracle Java SSL:
createSocket(Socket sock)
New signature for JSSE:
createSocket(Socket sock, String host, int port, boolean autoClose)
This method creates a new socket layered over an existing socket. Specify the existing socket, server host, server port, and whether to close the underlying socket when the created socket is closed.
There is a difference in the peer certificate chain returned by the SSL session object.
For Oracle Java SSL: The getPeerCertificateChain()
method of OracleSSLSession
returns a certificate chain with the root CA certificate first and the peer certificate last.
For JSSE: The getPeerCertificates()
method (preferred) or getPeerCertificateChain()
method (maintained for backward compatibility) of SSLSession
returns a certificate chain with the peer certificate first and the root CA certificate last.
Oracle Java SSL is deprecated in the OC4J 10.1.3.1 implementation but not yet desupported. (It will be desupported in future releases.)
For completeness, this section documents features specific to Oracle Java SSL, but we strongly recommend that you migrate to JSSE, as discussed in "Migrating from Oracle Java SSL to JSSE".
The following topics are covered here:
Note:
Depending on the JDK you use, Oracle Java SSL requires the filejssl-1_1.jar
or jssl-1_2.jar
to be in the classpath.See Also:
Oracle Advanced Security Administrator's Guide for information about Oracle Java SSL
In the OC4J 10.1.3.1 implementation, the JDK-default JSSE implementation is now the default SSL implementation for HTTPClient
. (This is a step toward deprecating Oracle Java SSL, the previous default SSL implementation for HTTPClient
.)
You can, however, explicitly specify Oracle Java SSL as the default SSL implementation for HTTPClient
by completing the following steps:
Specify the following system property setting:
HTTPClient.preferOracleSSL=true
Ensure that the Oracle Java SSL classes (for example, oracle.security.ssl.OracleSSLSocketFactory
) are in your classpath.
Important:
If an SSL socket factory (javax.net.ssl.SSLSocketFactory
implementation) is explicitly specified through the setSSLSocketFactory()
method of HTTPConnection
, the SSL implementation associated with the specified factory will be used, regardless of the setting of the HTTPClient.preferOracleSSL
property.To support client HTTPS connections for use with Oracle Java SSL, several methods were added to the HTTPConnection
class that use the Oracle Java SSL class, OracleSSLCredential
.
For Oracle Java SSL, security credentials are used to authenticate the server and the client to each other. OracleSSLCredential
is used to load user certificates and trust points from base64 or DER-encoded certificates. (DER, part of the X.690 ASN.1 standard, stands for Distinguished Encoding Rules.)
The API for Oracle Java SSL requires that security credentials be passed to the HTTP connection before the connection is established. The OracleSSLCredential
class is used to store these security credentials. Typically, a wallet generated by Oracle Wallet Manager is used to populate the OracleSSLCredential
object. Alternatively, individual certificates can be added by using an OracleSSLCredential
class API. After the credentials are complete, they are passed to the connection with the setSSLCredential()
method of the HTTPConnection
class.
Oracle client HTTPS uses SSL to provide security-aware applications support. When security-aware applications do not set trust points, SSL allows them to perform their own validation, letting the handshake complete successfully only if a complete certificate chain is sent by the peer. When applications authenticate to the trust point level, they are responsible for authenticating individual certificates below the trust point.
After the handshake is complete, the application must obtain the SSL session information and perform any additional validation for the connection.
Security-unaware applications that require the trust point check must ensure that trust points are set in the HTTPS infrastructure.
This section shows an application that uses HTTPClient
and Oracle Java SSL to connect to a Web server, send a GET
request, and fetch a Web page.
This section contains the sample code using HTTPClient
and Oracle Java SSL.
import HTTPClient.HTTPConnection; import HTTPClient.HTTPResponse; import oracle.security.ssl.OracleSSLCredential; import java.io.IOException; public class HTTPSConnectionExample { public static void main(String[] args) { if(args.length < 4) { System.out.println( "Usage: java HTTPSConnectionTest [host] [port] " + "[wallet] [password]"); System.exit(-1); } String hostname = args[0].toLowerCase(); int port = Integer.decode(args[1]).intValue(); String walletPath = args[2]; String password = args[3]; HTTPConnection httpsConnection = null; OracleSSLCredential credential = null; try { httpsConnection = new HTTPConnection("https", hostname, port); } catch(IOException e) { System.out.println("HTTPS Protocol not supported"); System.exit(-1); } try { credential = new OracleSSLCredential(); credential.setWallet(walletPath, password); } catch(IOException e) { System.out.println("Could not open wallet"); System.exit(-1); } httpsConnection.setSSLCredential(credential); try { httpsConnection.connect(); } catch (IOException e) { System.out.println("Could not establish connection"); e.printStackTrace(); System.exit(-1); } javax.servlet.request.X509Certificate[] peerCerts = null; try { peerCerts = (httpsConnection.getSSLSession()).getPeerCertificateChain(); } catch(javax.net.ssl.SSLPeerUnverifiedException e) { System.err.println("Unable to obtain peer credentials"); System.exit(-1); } String peerCertDN = peerCerts[peerCerts.length -1].getSubjectDN().getName(); peerCertDN = peerCertDN.toLowerCase(); if(peerCertDN.lastIndexOf("cn="+ hostname) == -1) { System.out.println("Certificate for " + hostname + " is issued to " + peerCertDN); System.out.println("Aborting connection"); System.exit(-1); } try { HTTPResponse rsp = httpsConnection.Get("/"); System.out.println("Server Response: "); System.out.println(rsp); } catch(Exception e) { System.out.println("Exception occured during Get"); e.printStackTrace(); System.exit(-1); } } }
This example uses a wallet created by Oracle Wallet Manager to set up credential information.
First, create the credentials and load the wallet:
mycredential = new OracleSSLCredential(); mycredential.setWallet(wallet_path, password);
After the credentials are created, pass them to your HTTPConnection
instance (here called httpsConnection
) through its setSSLCredential()
method. This method takes the OracleSSLCredential
instance, created in the first step, as input:
httpsConnection.setSSLCredential(mycredential);
The private key, user certificate, and trust points located in the wallet can now be used for the connection.
"Supported Default System Properties" discusses the Java system properties keyStore
, keyStorePassword
, keyStoreType
, trustStore
, trustStorePassword
, and trustStoreType
. This section discusses features relating to javax.net.ssl.keyStore
that are specific to Oracle Java SSL:
This property can be set to point to the text wallet file exported from Oracle Wallet Manager that contains the credentials that are to be used.
If no other credentials have been set for the HTTPS connection, then the file indicated by this property is opened when a handshake first occurs. If any errors occur as this file is read, then the connection fails and an IOException
is thrown.
If this property has no setting, the application is responsible for verifying that the certificate chain contains a certificate that can be trusted.
This section discusses how to specify cipher suites for Oracle Java SSL.
For Oracle Java SSL, Oracle.ssl.defaultCipherSuites
property can be set to a comma-delimited list of cipher suites. For example:
Oracle.ssl.defaultCipherSuites= SSL_RSA_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_WITH_RC4_128_MD5
You can set this property before establishing an SSL connection using Oracle Java SSL. The cipher suites that you specify in this property setting are used as the enabled cipher suites for new HTTPS connections.
See Also:
For Oracle Java SSL, you can also set cipher suites per connection by using the following method of the HTTPConnection
class in package HTTPClient
:
boolean setSSLEnabledCipherSuites(String[] cipherSuites)
This takes a Java string array, with each array element specifying a cipher suite. It returns a boolean indicating whether the current SSL implementation supports this method.
Note:
There is no way to specify cipher suites per HTTP connection in JSSE.See Also:
Oracle Application Server HTTPClient Java API Reference (Javadoc) for additional information
Oracle Java SSL supports the cipher suites listed in Table 16-1. Note that with NULL encryption, SSL is used only for authentication and data-integrity purposes.
Table 16-1 Cipher Suites Supported by Oracle Java SSL
Cipher Suite | Authentication | Encryption | Hash Function (Digest) |
---|---|---|---|
|
RSA |
3DES EDE CBC |
SHA1 |
|
RSA |
RC4 128 |
SHA1 |
|
RSA |
RC4 128 |
MD5 |
|
RSA |
DES CBC |
SHA1 |
|
RSA |
RC4 40 |
MD5 |
|
RSA |
DES40 CBC |
SHA1 |
|
DH anon |
3DES EDE CBC |
SHA1 |
|
DH anon |
RC4 128 |
MD5 |
|
DH anon |
DES CBC |
SHA1 |
|
DH anon |
RC4 40 |
MD5 |
|
DH anon |
DES40 CBC |
SHA1 |
|
RSA |
NULL |
SHA1 |
|
RSA |
NULL |
MD5 |