Oracle HTTPClient security supports the Secure Sockets Layer (SSL) on client HTTP connections with the package
HTTPClient.This chapter describes the basic features of
HTTPClient, how to configure it with system properties, and how to use it with the standard Java Secure Socket Extension (JSSE) or with NTLM authentication.
This chapter is divided in the following sections:
For general information about JSSE, see
Oracle HTTPClient security implements the package
HTTPClient.HTTPConnection and provides a comprehensive set of functions that allows the creation of HTTP connections (secured or otherwise) between a source and a target. The Oracle implementation of the class
HTTPClient diverges from the original open source version upon which it is based, and even though many similarities between them remain, the two implementations are not necessarily compatible with each other.
For further details about JSSE and
java.net, see information in the following links:
Support for JKS and PKCS12 (Oracle Wallet) keystores. Starting with this release, however, the JKS keystore is the preferred keystore for use with HTTPClient. Any Oracle Wallet usage with HTTPClient should be switched over to JKS usage.
HTTPS tunneling through proxies
HTTP proxy authentication
(Limited) Support of the
Oracle HTTPClient supports the use of the protocols HTTP 1.0 and HTTP 1.1 for communication between client and server, and the JSSE SSL implementation. Note that without adding OraclePKIProvider to the JVM, Oracle Wallets cannot be used. See Prerequisites for using JSSE.
The following four sections describe in detail the major features supported by Oracle HTTPClient security.
Starting with this release, an application should use only a JKS keystore with Oracle HTTPClient. The JKS keystore is the default keystore in Java and no JVM settings are required to use this keystore. Applications that want to migrate the content of their existing Oracle Wallets to JKS can use
The choice of data format in a keystore depends on the choice of the security provider configured in the JVM. If you choose the default Sun Microsystems security provider, then you must use a JKS-formatted keystore. If you choose the
oracle.security.pki.OraclePKIProvider, which should be registered with the JVM, then you must use the keystore formats PKCS12 or SSO (auto-login) Oracle wallet.
PKCS12 and JKS are standard keystore formats; SSO Oracle wallet is an Oracle proprietary format.
Wallets formatted with PKCS12 or SSO contain all their credentials encrypted; the main difference between these two keystores is that, in case of an SSO wallet, a password to open the wallet to access information in it is not required.
For details about using the
orapki command to migrate an Oracle Wallet to JKS, see section H.1.6 Converting Between Oracle Wallet and JSK Store in Oracle Fusion Middleware Administrator's Guide.
For further details about Oracle Wallets, see chapter Oracle Wallet Manager and orapki in Oracle Fusion Middleware Administrator's Guide.
Applications can access information about an established SSL connection using the method
getSSLSession in the class
HTTPConnection in the Oracle package
HTTPClient. After a connection has been established, applications can retrieve connection information such as the cipher suite used for the connection and the peer certificate chain.
A user of the
java.net.URL framework may configure JSSE according to the system properties listed in the following document (JSSE Reference Guide):
A cipher is an algorithm that performs encryption and decryption, and a cipher suite is a set of such algorithms. Before data can flow through an SSL connection, both sides of the connection must negotiate and agree on the various connection parameters, including the common cipher to use for data transmission. Selecting a particular cipher and related SSL connection parameters allows the communicating participants to establish the appropriate security level on the transmission channel.
The following choice of parameters of a secure transmission are recommended:
When null encryption is chosen, SSL performs only authentication and data integrity checks. The system
property https.cipherSuites specifies the subset of available cipher suites (comma-delimited list of cipher suite names).
This section describes some standard JSSE system keystore properties used to set security credential information.
This property indicates the location and name of the keystore or wallet file to use as the keystore.
This property indicates the password necessary to open the keystore (keystore or wallet file). Specifying the keystore password in Java system property may pose a security risk in some environments.
To avoid this risk, if a password is necessary, do not store it in a clear text. Alternatively, use the method
System.setProperty to set it dynamically (before starting the
HTTPConnection) and then unset it after the handshake is completed. Note, however, that this still may present the security risk since another application running in the server may read the password by polling this property.
This property indicates the type of file used for the keystore. When using the OraclePKIProvider, the value can be PKCS12 or SSO; when using the default Sun Microsystems JSSE implementation, the value must be JKS.
This property, similar to
javax.net.ssl.keyStore, indicates the location and name of the keystore or wallet file to use as the truststore.
This property, similar to
javax.net.ssl.keyStorePassword, indicates the password necessary to open the truststore file (keystore or wallet).
This property, identical in function to the property
javax.net.ssl.keyStoreType, indicates the type of file used for the truststore.
This section describes the requirements for using and configuring Oracle HTTPClient with JSSE. The information applies only to scenarios where Oracle HTTPClient is used with Oracle Wallet.
By default, HTTPClient uses the JSSE implementations available in the JVM.
HTTPClient with JSSE:
Use Sun Microsystems JDK version 1.2 or higher (JSSE is included as part of JDK 1.4 or higher).
If Oracle wallet support is required, include the file
oraclepki.jar in your classpath. Note that the files
jssl-1_2.jar (used by Oracle Java SSL) are no longer required.
Note:Starting with this release, an application should use only a JKS keystore with Oracle HTTPClient. The JKS keystore is the default keystore in Java and no JVM settings are required to use this keystore. Application wanting to migrate the content of their existing oracle Wallets to JKS can use
This step is necessary only if you are using Oracle Wallet. Register the OraclePKIProvider with the JVM, by using either of the following steps:
Edit the file
jre/lib/security/java.security, by adding an entry similar to
n is replaced with the appropriate index number.
Call the method
HTTPClientuses the JVM JSSE
SSLSocketFactory, which recognizes the SSL-related system properties. An application can, however, construct its own JSSE
SSLSocketFactoryfor HTTPClient to use. This custom
SSLSocketFactorycould be designed to support multiple keystores or truststores and to ignore SSL-related system properties.
Also, by default,
HTTPClient uses the JVM JSSE implementation. If, however, the Sun SSL provider is configured, the cacerts file is used as a truststore based on the rules defined in
HTTPClient to use JSSE as the underlying SSL provider, proceed as follows:
This step is necessary only if not using the JDK infrastructure.
Create a truststore using the Sun Microsystems utility
keytool. For details about this tool usage, see
Assign the truststore to the underlying SSL provider. For the Sun JSSE provider, set the system properties
javax.net.ssl.trustStorePassword. Oracle discourages setting passwords in system properties, and some truststore types may not require password for read access.
Create an instance of
HTTPClient.HTTPConnection, as illustrated in the following code sample:
HTTPConnection conn = new HTTPConnection( "https", "my.bank.com", -1 );
connect to establish the SSL connection and get SSL session info, as illustrated in the following code sample:
conn.connect(); SSLSession sessionInfo = conn.getSSLSession();
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 risk requires that HTTPS servers have certificates issued to their host name. Then, it is the responsibility of the client to perform the validation after the SSL connection is established.
Oracle HTTP Client Security uses a host name verifier (an implementation of the interface
javax.net.ssl.HostnameVerifier) to attest that the host name in an SSL certificate matches the host name in the URI used to access the protected server.
HTTPClient invokes the
HostnameVerifier instance immediately after establishing an SSL session and throws the exception
javax.net.ssl.SSLPeerUnverifiedException if it detects a host name mismatch.
Important:You can use your own implementation of the host name verifier or the one provided by Oracle (as described below). Any such implementation must contain a constructor with no arguments.
For further details about the class
Host name verification is performed only if it is enabled by a system property or programmatically, as described in the following two sections.
To enable host name verification without having to alter your code, set the system property
HTTPClient.defaultHostnameVerifier to the full name of the class implementing the interface
To enable host name verification programmatically, use:
This method sets the host name verifier for all connections in the entire Java VM to the passed instance. It returns the host name verifier previously set as default (if there was one) or null (if the host name verification was disabled for the Java VM).
This method sets the verifier for the connection to the passed instance and overrides any default setting; if the passed argument is null, it disables the host name verification for the connection. It returns the host name verifier previously set for the connection (if there was one) or null (if the host name verification was disabled for the connection).
StandardHostnameVerifier compares (case-insensitive) the SSL session host name and the common name (CN) of the distinguished name (DN) from the first certificate in the SSL certificate chain; moreover, it allows the use of wildcard characters while attempting to match both names during the comparison. For example, if wildcard is enabled, the strings “*.oracle.com” and “www.oracle.com” match.
StandardHostnameVerifier exposes the following methods:
boolean setRecognizeWildcardCNs(boolean recognizeWildcardCNs)
This method sets the comparison to recognize or not to recognize wildcard characters; it returns the value previously set.
This method returns true is the comparison uses wildcards, or false otherwise.
boolean verify(java.lang.String hostname, javax.net.ssl.SSLSession sslSession)
This method returns true, if the passed hostname matches the authentication scheme of the server in the passed session, or false otherwise.
The following line illustrates how to set the Oracle host name verifier as the default host name verifier with a system property:
To perform further validation (beyond host name verification) by using the data in the object returned by the method
getSSLSession, proceed as follows. First, establish a connection to the server without transferring any data:
Next, obtain a session info:
SSLSession sessionInfo = httpsConnection.getSSLSession();
SSLSession exposes many attributes of the SSL connection which may be used to verify the connection. For details, see
NT LAN Manager (NTLM) is a Microsoft authentication protocol supported by Oracle HTTPClient that clients, proxies, and servers can use.
NTLM is a connection-oriented protocol because after a connection is authenticated no further credentials are required for transmission while the connection remains open. Thus, a client using NTLM proves its identity to establish the connection and need not send its password thereafter.
Proxy servers may also use NTLM for client authentication, but, unlike some request-oriented authentication schemes (such as Basic and Digest authentication), an NTLM client authenticates its connection with only the proxy server, not the resource server.
An NTLM account identifier has the format
NTDname\userName, where the optional string
NTDname identifies the NT Domain name; if not present, the domain name is assumed to be the default NT Domain name, which is set with the system property
HTTPClient.ntlm.defaultDomainName. Furthermore, if the account identifier contains no NT Domain name and there is no default set, then the NTLM-protected server uses its own NT Domain name.
A realm, as specified in some authentication schemes (such as Basic authentication), does not apply to NTLM since the challenge does not have a realm directive; thus, all NTLM credentials are assumed to be part of the same empty realm within an HTTPClient connection.
To connect to an NTLM-protected resource or proxy server, credentials must be added to the HTTPClient AuthorizationInfo credential store. This is accomplished in one of two ways according to the type of server to which the client is connecting. In any case,
HTTPClient automatically queries the credential store when challenged by an NTLM server.
To connect to an NTLM-protected resource server, add NTLM credentials using the HTTPConnection instance as illustrated in the following code snippet:
HTTPConnection conn = new HTTPConnection( myHost, myPort ); conn.addNtlmAuthentication( myUsername, myPassword ); HTTPResponse response = conn.Get( "/index.htm" ); int status = response.getStatusCode(); assertEquals( 200, status );
Note that the example above adds NTLM credentials for the resource server represented in myHost.
Alternatively, add NTLM credentials using the object AuthorizationInfo directly as illustrated in the following code snippet:
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 );
Note that the example above adds NTLM credentials for the proxy server represented in myProxyHost.
To connect to an NTLM-protected proxy server, add NTLM credentials using
HTTPConnection.addNtlmAuthentication directly, as illustrated above, since the method
addNtlmAuthentication adds credentials for the associated resource server, not the proxy server.