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.
- IBMJCE, an IBM security provider available in earlier versions of IBM SDK's for z/OS, is not available in IBM Semeru Runtime Certified Edition for z/OS, Version 11. The JCERACFKS keystore IBMJCE provided is now provided by IBMZSecurity. All other functionality IBMJCE provided is now provided by the OpenJCEPlus and OpenJDK providers.
- Unlike IBMJCE, IBMZSecurity is not a default provider in IBM Semeru Runtime Certified Edition for z/OS, Version 11. IBMZSecurity must be added manually on the $JAVA_HOME/conf/security/java.security file on z/OS or programmatically:
Security.addProvider(new com.ibm.crypto.zsecurity.provider.IBMZSecurity());
- IBMZSecurity must be enabled for proper usage of the JCEHYBRIDRACFKS keystore. To do so otherwise, is an unsupported configuration.
- The methods getIBMJCEPrivateKey() and setIBMJCEPrivateKey(), used for interacting with the JCERACFKS aspect of JCEHYBRIDRACFKS, have been deprecated and it is recommended to use the new methods getSoftwareJCEPrivateKey() and setSoftwareJCEPrivateKey() since IBMJCE is no longer present. The 'SoftwareJCE' substring distinguishes itself from the hardware representation of JCEHYBRIDRACFKS, accessed as the JCECCARACFKS keystore and implemented by the IBMJCECCA provider.
-
The java.protocol.handler.pkgs is no longer required in IBM Semeru Runtime Certified Edition for z/OS, Version 11.0.
- The
safkeyring
URLs are now dependent on the type of RACF keystore as seen below. - The URL for a JCEHYBRIDRACFKS keystore is now
safkeyringjcehybrid
- The URL for a JCECCARACFKS keystore is now
safkeyringjcecca
- The URL for a JCERACFKS keystore is now
safkeyringjce
- The
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:
- IBMJCEHYBRID
- IBMJCECCA
- IBMZSecurity
- 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:
- IBMJCEHYBRID gets control and routes the request to IBMJCECCA.
- If IBMJCECCA is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception and attempts to failover to IBMZSecurity.
- If IBMZSecurity is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception and attempts to failover to OpenJCEPlus.
Example 2
JCE providers in the JVM security provider list are as follows:
- IBMJCEHYBRID
- IBMJCECCA
- 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:
- IBMJCEHYBRID gets control and routes the request to OpenJCEPlus
- If OpenJCEPlus is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception, wraps it in an IBMJCEHybridException and throws it to the application.
Example 3
JCE providers in the JVM security provider list are as follows:
- IBMJCEHYBRID
- IBMJCECCA
- 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:
- IBMJCEHYBRID gets control and routes the request to IBMJCECCA.
- If IBMJCECCA is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception and attempts to failover to OpenJCEPlus.
- If OpenJCEPlus is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception, wraps both the exception thrown by IBMJCECCA and the exception thrown by OpenJCEPlus in an IBMJCEHybridException and throws it to the application.
Example 4
JCE providers in the JVM security provider list are as follows:
- OpenJCEPlus
- IBMJCECCA
- 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:
- OpenJCEPlus gets control.
- OpenJCEPlus is unable to process the request and throws an exception.
- The exception is passed back to the application. (No failover is done because IBMJCEHYBRID does not get control.)
Example 5
JCE providers in the JVM security provider list are as follows:
- IBMJCECCA
- OpenJCEPlus
Situation:
- An application invokes Security.insertProviderAt(new com.ibm.crypto.ibmjcehybrid.provider.IBMJCEHYBRID, 1)
- The application requests a serviceType.algorithm supported by both IBMJCECCA and OpenJCEPlus. The application does not specify a provider on getInstance().
Processing flow:
- IBMJCEHYBRID gets control and routes the request to IBMJCECCA.
- If IBMJCECCA is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception and attempts to failover to OpenJCEPlus.
Example 6
JCE providers in the JVM security provider list are as follows:
- IBMJCEHYBRID
- IBMJCECCA
- OpenJCEPlus
Situation:
- An application invokes Security.insertProviderAt(new mypkg.MyProvider, 1)
- The application requests a serviceType.algorithm supported by MyProvider, by IBMJCECCA, and by OpenJCEPlus. The application does not specify a provider on getInstance().
Processing flow:
- MyProvider gets control.
- MyProvider is unable to process the request and throws an exception.
- The exception is passed back to the application. (No failover is done because IBMJCEHYBRID does not get control.)
Example 7
JCE providers in the JVM security provider list are as follows:
- IBMJCEHYBRID
- IBMJCECCA
- OpenJCEPlus
Situation:
- An application invokes Security.insertProviderAt(new mypkg.MyProvider, 3)
- The application requests a serviceType.algorithm supported by MyProvider, by IBMJCECCA, and by OpenJCEPlus. The application does not specify a provider on getInstance().
Processing flow:
- IBMJCEHYBRID gets control and routes the request to IBMJCECCA.
- If IBMJCECCA is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception and attempts to failover to OpenJCEPlus.
- If OpenJCEPlus is unable to process the request it throws an exception, IBMJCEHYBRID catches the exception, wraps both the exception thrown by IBMJCECCA and the exception thrown by OpenJCEPlus in an IBMJCEHybridException and throws it to the application. (There is no failover to MyProvider because it was not in the provider list at JVM initialization.)
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,
- Passing specification information, such as chaining mode or padding scheme, will not prevent failover to another provider.
- Passing data, such as an encryption key or bytes of data to be encrypted, will prevent failover after the first time. That is, if there is a failure during the first call that passes data, IBMJCEHYBRID will attempt failover. If the first such call is successful then failover is disabled for the object until after a reset operation, even if the subsequent failure is in a method that does not itself prevent failover.
- A reset, explicit or implicit, will reenable failover. An explicit reset occurs when an implementation SPI has a reset() method and it is called by an application. An implicit reset occurs when an application calls a method that includes a reset operation, as described in the Java Specification. Examples of methods that include reset are the Cipher SPI doFinal() method and the Signature SPI sign() and verify() methods.
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.)
The following illustrates how to retrieve the embedded exceptions from the
IBMJCEHybridException
programatically.
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.
Note that IBMJCEHYBRID can also be enabled by an application invoking
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.
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.
The same syntax is used to specify the keyring and userid as used with a JCERACFKS or JCECCARACFKS keystore. For example
See additional information regarding the IBMJCEHYBRIDRACF keystore and key objects in the IBMJCEHYBRID provider javadoc by referencing the following classes
Copyright © 2010-2022 IBM Corporation, Inc. All Rights Reserved. |