Introduction

During JVM initialization, the Java Security Framework loads each security provider listed in the java.security provider list. When a provider initializes itself, it registers with the Java Security Framework for each serviceType.algorithm that it can perform. If an application requests cryptographic services without specifying a security provider, the Java Security Framework selects the first provider in the security provider list that registered the requested service.

An application that uses services provided by security providers can specify the provider it wants to use. However, applications don't usually do this because it makes them less portable and less flexible. In addition, by using the installation-configured provider list, an application can take advantage of crytographic features when running on a platform that includes them and also can run successfully on a platform that does not include cryptographic features.

Because a platform with cryptographic features (such as cryptographic hardware and cryptographic processors) can be volatile, a security provider might register for a serviceType.algorithm that it is unable to perform when requested. In this case, the security provider will throw an exception that is passed up to the application. If the application retries the operation, the Security Framework will pass the request to the same provider because it is still first in the list. Unless there is a change in the status of cryptographic features on the platform, the result will be the same. Thus the application will be unsuccessful, even if another provider registered for the serviceType.algorithm could successfully process the request.

The IBM JCE Hybrid Provider is designed to provide failover from one JCE security provider to another in a manner that is transparent to applications.

IBM Semeru Runtime Certified Edition for z/OS, Version 11 Updates

There are numerous runtime environment contains changes compared to earlier releases, such as IBM® SDK, Java™ Technology Edition, Version 8.

When migrating an existing or exploiting a new workload, please consult the following links to better understand the nature of the changes in IBM Semeru Runtime Certified Edition for z/OS, Version 11.0.

IBMJCEHYBRID Failover with JCE Providers

IBMJCEHYBRID does not perform any cryptographic operations, but routes requests to JCE providers that have registered with the Java Security Framework. When IBMJCEHYBRID is the first JCE provider in the active JVM provider list (initialized using the java.security provider list), IBMJCEHYBRID routes requests to and provides failover for JCE providers according to the security provider registrations done at JVM initialization. This enables an application to take advantage of cryptographic features when they are available on the platform and to use a provider that does not depend on these features when they are not available.

If IBMJCEHYBRID is not the first JCE provider in the active JVM provider list then a cryptographic request might be routed to a different JCE provider instead of IBMJCEHYBRID. If this happens, IBMJCEHYBRID does not get control and cannot provide routing or failover for the request. The IBMJCEHYBRID can be the first JCE provider in the java.security provider list but not be the first JCE provider in the active JVM provider list. This will be the case if an application uses the Security.insertProviderAt() API and inserts a provider ahead of IBMJCEHYBRID.

The list of serviceType.algorithm pairs for which IBMJCEHYBRID provides failover is the list of serviceType.algorithm pairs supported by the IBMJCECCA, OpenJCEPlus, and IBMZSecurity providers, with the exception of algorithms in the KeyStore service. Using this list, IBMJCEHYBRID provides failover from, and to, each provider in the java.security provider list, whether it is an IBM security provider, a security provider written by the customer, or a third party security provider.

KeyStore support is, in general, very specific to the implementing provider. In other words, if a provider can not satisfy a KeyStore request for a KeyStore that it implements then it is very unlikely that another provider can satisfy a request for that KeyStore. For this reason, IBMJCEHYBRID does not attempt failover for any KeyStore.algorithm. When the Java Security Framework receives a request for a serviceType.algorithm that IBMJCEHYBRID has not registered, then the Framework routes the request to the first security provider that has registered for it.

IBMJCEHYBRID routes requests to and provides failover for only those providers that are in the java.security provider list when the JVM initializes the Security Framework. If an application uses the Security.insertProviderAt() API to insert a JCE provider after IBMJCEHYBRID, IBMJCEHYBRID will continue to be the preferred provider and will continue to provide failover support. However, IBMJCEHYBRID will not route requests to or provide failover for the provider that was inserted. Consequently, unless an application specifies the inserted JCE provider on the getInstance() API, it will receive control only for serviceType.algorithm pairs that IBMJCEHYBRID did not register.

If a JCE provider in the active JVM provider list has dependencies on cryptographic features that are offline then repeated calls to that provider will impose a performance penalty. To reduce the effect of this performance penalty, if a provider fails to process a request for a serviceType.algorithm it registered, that provider is marked 'inactive' for that serviceType.algorithm. Because the cryptographic features might become available, inactive providers are periodically restored to 'active' status based on a number of factors, including how often there is a getInstance() for the serviceType.algorithm and the state of the active providers list when request failovers are processed. If a request cannot be processed by any active provider, all inactive providers are restored to active status and IBMJCEHYBRID attempts to failover to each of them in turn.

Examples of IBMJCEHYBRID Failover with JCE Providers

The following examples illustrate the failover service provided by IBMJCEHYBRID:

Example 1

JCE providers in the JVM security provider list are as follows:

  1. IBMJCEHYBRID
  2. IBMJCECCA
  3. IBMZSecurity
  4. OpenJCEPlus

Situation: An application requests a serviceType.algorithm supported by IBMJCECCA, IBMZSecurity, and OpenJCEPlus. The application does not specify a provider on getInstance().

Processing flow:

Example 2

JCE providers in the JVM security provider list are as follows:

  1. IBMJCEHYBRID
  2. IBMJCECCA
  3. OpenJCEPlus

Situation: An application requests a serviceType.algorithm supported by OpenJCEPlus but not supported by IBMJCECCA. The application does not specify a provider on getInstance().

Processing flow:

Example 3

JCE providers in the JVM security provider list are as follows:

  1. IBMJCEHYBRID
  2. IBMJCECCA
  3. OpenJCEPlus

Situation: An application requests a serviceType.algorithm supported by both IBMJCECCA and OpenJCEPlus. The application does not specify a provider on getInstance().

Processing flow:

Example 4

JCE providers in the JVM security provider list are as follows:

  1. OpenJCEPlus
  2. IBMJCECCA
  3. IBMJCEHYBRID

Situation: An application requests a serviceType.algorithm supported by both IBMJCECCA and OpenJCEPlus. The application does not specify a provider on getInstance().

Processing flow:

Example 5

JCE providers in the JVM security provider list are as follows:

  1. IBMJCECCA
  2. OpenJCEPlus

Situation:

Processing flow:

Example 6

JCE providers in the JVM security provider list are as follows:

  1. IBMJCEHYBRID
  2. IBMJCECCA
  3. OpenJCEPlus

Situation:

Processing flow:

Example 7

JCE providers in the JVM security provider list are as follows:

  1. IBMJCEHYBRID
  2. IBMJCECCA
  3. OpenJCEPlus

Situation:

Processing flow:

IBMJCEHYBRID Failover and Security Object State

As described in the previous section, the ability of IBMJCEHYBRID to provide failover depends on the JCE security providers that have registered with the Java Security Framework. The ability of IBMJCEHYBRID to provide failover also depends on the state of the security object, specifically on the type of data that has been passed to the security object.

In general,

If Failover is unsuccessful: IBMJCEHybridException

As described in the preceding sections, IBMJCEHYBRID provides failover when JCE providers are unable to complete cryptographic operations. Depending on the circumstances of the request and the platform environment, failover may not be successful. For example, failover could be unsuccessful due to the state of the operation when failover was attempted or due to an incorrectly formed request.

If failover is successful, it is transparent to the application. In this case, no error is reported and no exception is thrown.

If failover is not successful, IBMJCEHYBRID throws an IBMJCEHybridException containing the exception (and stack trace) thrown by each JCE provider that attempted the operation. These embedded exceptions are included in the output from printStackTrace(). The embedded exceptions can also be retrieved programmatically.

The following is an example of the output from ex.printStackTrace() where ex is an IBMJCEHybridException. In this example, IBMJCECCA was first in the provider list for the RSA Cipher and OpenJCEPlus was second (and last). IBMJCECCA failed the request with a ShortBufferException. OpenJCEPlus failed the request because the key was an IBMJCECCA hardware key, a format not recognized by OpenJCEPlus. (Note that both IBMJCECCA and OpenJCEPlus recognize the format of an OpenJCEPlus key (PKCS#8). If the key had been in this format, failover would have resulted in two ShortBufferExceptions.)

IBMJCEHybridException: Failover exhausted, all registered providers attempted and failed. Exception#0 javax.crypto.ShortBufferException: Output buffer too short: 25 bytes given, 30 bytes needed Stack Trace: at com.ibm.crypto.hdwrCCA.provider.RSA.engineDoFinal(RSA.java:807) at javax.crypto.Cipher.doFinal(Unknown Source) at com.ibm.crypto.ibmjcehybrid.provider.HybridCipher.doFinal(HybridCipher.java:2312) . . . Exception#1 java.security.InvalidKeyException: Bad key encoding Stack Trace: at com.ibm.crypto.plus.provider.RSA.engineInit(Unknown Source) at javax.crypto.Cipher.init(Unknown Source) at com.ibm.crypto.ibmjcehybrid.provider.HybridCipher.init(HybridCipher.java:952) . . .

The following illustrates how to retrieve the embedded exceptions from the IBMJCEHybridException programatically.

import com.ibm.crypto.ibmjcehybrid.provider.IBMJCEHybridException; . . . try { . . . } catch (Exception ex) { if (ex instanceof IBMJCEHybridException) { Vector<Exception> exVector = ex.getEmbeddedExceptionVector(); if (null != exVector) { int exCount = exVector.size(); Exception[] exceptions = exVector.toArray(new Exception[exCount]); for (int x=0; x<exCount; x++) { // process the exception exceptions[x] } // end for } // end if } else { // not an IBMJCEHybridException // process the exception ex } // end else Throwable cause = ex.getCause(); if (null != cause) { // process the exception cause } // end if } // end catch

Configuration Details

To enable the IBMJCEHYBRID provider, you can add it as the first JCE provider in the provider list in $JAVA_HOME/lib/security/java.security.

The following example shows the configuration needed for IBMJCEHYBRID to provide failover from the IBMJCECCA provider to the OpenJCEPlus provider for serviceType.algorithm pairs for which both are registered.

. . <lines omitted> . # # List of providers and their preference order: # security.provider.1=IBMJCEHYBRID security.provider.2=IBMJCECCA security.provider.3=IBMZSecurity security.provider.4=OpenJCEPlus security.provider.5=SUN security.provider.6=SunRsaSign security.provider.7=SunEC security.provider.8=SunJSSE security.provider.9=SunJCE . . <lines omitted> .

Note that IBMJCEHYBRID can also be enabled by an application invoking

Security.insertProviderAt( new com.ibm.crypto.ibmjcehybrid.provider.IBMJCEHYBRID, 1);

However, this might impact the portability of the application.

JCEHYBRIDRACFKS KeyStore Implementation

The IBMJCEHYBRID provider contains a KeyStore implementation called JCEHYBRIDRACFKS. This keystore allows a user to load a single SAF keyring as both a JCECCARACFKS keystore (implemented by IBMJCECCA) and JCERACFKS keystore (IBMZSecurity) representation.

Note that IBMZSecurity must be added to the security provider list to make use of the JCERACFKS keystore. Otherwise, the JCEHYBRIDRACFKS is not properly configured.

When a SAF keyring is loaded as a JCEHYBRIDRACFKS KeyStore the keyring will be loaded as both a JCECCARACFKS and a JCERACFKS keystore. The key material from both of these keystores will be combined together and represented by the JCEHYBRIDRACFKS keystore. The various pieces that are to be available by the user of the JCEHYBRIDRACFKS KeyStore can be described by the following table. The left most column shows the keyring being loaded, the middle column shows the results of what will be available when ICSF is turned on and no errors occur during loading of the keystore, and the right most column shows the results of what will be available when ICSF is turned off or errors occur during loading of the keystore.

Note that any certificates/keys in the table ending with the name CCA have their key material located within ICSF. Additionally, IBMZSecurity private key means a key derived by IBMZSecurity by either SUN, SunRsaSign, and OpenJCEPlus providers.

Keyring Being Loaded ICSF Turned On ( During Load ) Keystore Contents Available ICSF Turned Off ( During Load ) Keystore Contents Available
Ring:
  >Keyring<

Certificate   Cert Owner     USAGE       DEFAULT
-------------------------------------------------
JayCa         ID(G910501)   CERTAUTH     NO
JayEndUser    ID(G910501)   PERSONAL     YES
                    
JayCa entry contains:
   Certificate

JayEndUser entry contains:
   Certificate
   Certificate chain
   IBMJCECCA private key
   IBMZSecurity private key
                    
JayCa entry contains:
   Certificate

JayEndUser entry contains:
   Certificate
   Certificate chain
   IBMZSecurity private key
                    
Ring:
  >KeyringCCA<

Certificate   Cert Owner     USAGE       DEFAULT
-------------------------------------------------
JayCaCCA      ID(G910501)   CERTAUTH     NO
JayEndUserCCA ID(G910501)   PERSONAL     YES
                    
JayCaCCA entry contains:
   Certificate

JayEndUserCCA entry contains:
   Certificate
   Certificate chain
   IBMJCECCA private key
                    
JayCaCCA entry contains:
   Certificate

JayEndUserCCA
   Alias will be unavailable since ICSF is down and key resides in ICSF.

JayCa entry contains:
Certificate

JayEndUser entry contains:
   Certificate
   Certificate chain
   IBMZSecurity private key
                    
Ring:
  >KeyringMix<

Certificate   Cert Owner     USAGE       DEFAULT
-------------------------------------------------
JayCa         ID(G910501)   CERTAUTH     NO
JayEndUser    ID(G910501)   PERSONAL     NO
JayCaCCA      ID(G910501)   CERTAUTH     NO
JayEndUserCCA ID(G910501)   PERSONAL     YES
                    
JayCa entry contains:
   Certificate

JayCaCCA entry contains:
   Certificate

JayEndUserCCA entry contains:
   Certificate
   Certificate chain
   IBMJCECCA private key

JayEndUser entry contains:
   Certificate
   Certificate chain
   IBMJCECCA private key
   IBMZSecurity private key
                    
JayCa entry contains:
   Certificate

JayCaCCA entry contains:
   Certificate

JayEndUserCCA
   Alias will be unavailable since ICSF is down and key resides in ICSF.

JayEndUser entry contains:
   Certificate
   Certificate chain
   IBMZSecurity private key
                    

When loaded the new JCEHYBRIDRACFKS will contain a combination of the key and certificate material from both the JCECCARACFKS and JCERACFKS keystore representations of the same SAF keyring. This combination will be stored in a key container which contains all of the available key material from both keystores. It should be noted that IBMZSecurity does not generate keys itself but fetches keys from the SUN, SunRsaSign, and OpenJCEPlus providers for the DSA, RSA, and EC algorithms respectively. Please see the IBMJCECCA documentation titled z/OS Unique Considerations for more information regarding the JCECCARACFKS and JCERACFKS keystores.

KeyStore operations that create new entries or update existing entries will accept either a key derived by the IBMZSecurity provider or a key derived from the IBMJCECCA provider and will store them in the instance of the JCEHYBRIDRACFKS keystore along with inserting them into the underlying keystore of choice. Keys derived from the IBMJCECCA provider will be inserted into the underlying JCECCARACFKS keystore, keys derived by the IBMZSecurity provider will be inserted into the underlying JCERACFKS keystore. Note that IBMZSecurity does not generate keys itself but fetches keys from the SUN, SunRsaSign, and OpenJCEPlus providers for the DSA, RSA, and EC algorithms respectively.

KeyStore operations that return key entries will return a new private key called HybridRACFPrivateKey. KeyStore operations that return generic certificate objects will return certificates. This means that the exact nature of the key or certificate returned by KeyStore APIs (getKey(), getCertificate(), and getCertificateChain()) does not always need to be known to the application. The HybridRACFPrivateKey or certificate can be retrieved and passed to an instance of the crypto API as a generic Key or Certificate object. That being said only cipher and signature instances derived from the IBMJCEHYBRID provider will be able to make use of the new HybridRACFPrivateKey object for RSA signature and cipher operations.

An alternative to using the cipher and signature operations in the IBMJCEHYBRID provider would be to extract software JCE or IBMJCECCA implementations from the HybridRACFPrivateKey and use that implementation with the software JCE or IBMJCECCA providers. The HybridRACFPrivateKey key implementations that are returned from the JCEHYBRIDRACFKS keystore can potentially contain both the software JCE and IBMJCECCA representations of the same key. A user may decide to fetch one or the other representation for use with the software JCE or IBMJCECCA providers respectively. For example the following code snippet extracts the software JCE representation of the HybridRACFPrivateKey and uses SunRsaSign to encrypt and decrypt a piece of data. Note that OpenJCEPlus or SUN can also be used as the provider for instantiating the cipher object in this example.

HybridRACFInputStream his = new HybridRACFInputStream(userid, keyring, passwordChars); KeyStore ks = KeyStore.getInstance("JCEHYBRIDRACFKS","IBMJCEHYBRID"); ks.load(his,passwordChars); HybridRACFPrivateKey privKey = (HybridRACFPrivateKey)ks.getKey(alias,passwordChars); PublicKey pubKey = (PublicKey)ks.getCertificate(alias).getPublicKey(); //Encrypt with SunRsaSign Cipher cipher = Cipher.getInstance("RSA", "SunRsaSign"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); byte[] cipherText = cipher.doFinal(plainText); //Decrypt with SunRsaSign cipher.init(Cipher.DECRYPT_MODE, privKey.getSoftwareJCEPrivateKey()); byte[] decipheredText = cipher.doFinal(cipherText);

When a user calls the store() method of the JCEHYBRIDRACFKS keystore the code will attempt to write all entries back out to the specified SAF keyring. All entries with keys derived from software JCE providers will be stored as if inserted from a JCERACFKS KeyStore. All entries with keys derived from IBMJCECCA will be stored as if inserted from a JCECCARACFKS KeyStore.

A URL handler exists to allow the URL class to open the JCEHYBRIDRACFKS keystore. To make use of this new URL handler the caller must specify the following java environment variable.

java.protocol.handler.pkgs=com.ibm.crypto.ibmjcehybrid.provider

The same syntax is used to specify the keyring and userid as used with a JCERACFKS or JCECCARACFKS keystore. For example

"safkeyring://userid/keyring"

See additional information regarding the IBMJCEHYBRIDRACF keystore and key objects in the IBMJCEHYBRID provider javadoc by referencing the following classes

com.ibm.crypto.ibmjcehybrid.provider.HybridRACFInputStream com.ibm.crypto.ibmjcehybrid.provider.HybridRACFKeyStore com.ibm.crypto.ibmjcehybrid.provider.HybridRACFOutputStream com.ibm.crypto.ibmjcehybrid.provider.HybridRACFPrivateKey com.ibm.crypto.ibmjcehybrid.provider.safkeyring.Handler

Trademarks

IBM is a trademark or registered trademark of International Business Machines Corporation in the United States, or other countries, or both.

Oracle and Java are registered trademarks of Oracle and/or its affiliates.

Other company, product, or service names may be trademarks or service marks of others.


Copyright © 2010-2022 IBM Corporation, Inc. All Rights Reserved.