What is IBMJCEHYBRID?
IBMJCEHYBRID is an IBM z/OS Java security provider that routes cryptographic application requests to different JCE providers, depending on their availability and capabilities . Many Java security providers rely on cryptographic hardware, facilities, and APIs that operate on the mainframe. These services provide strong & secure cryptographic algorithms, along with faster speed and security than operations performed using software. While these services are reliable and allow many IBM providers to function, they can also be volatile.
In the event that a hardware, API, or service is not configured properly or is temporarily unavailable, this circumstance could cause a security provider that relies on one or more of these services to become disabled and, ultimately, break the Java application. We obviously do not want our applications to break - especially in production. So, how do we address this concern - with IBMJCEHYBRID!
How IBMJCEHYBRID can help your Java apps
IBMJCEHYBRID is designed to provide failover from one JCE provider to the next depending on their current availability. IBMJCEHYBRID does not perform the cryptographic operations itself, but rather routes the operation to its succeeding JCE providers until it can successfully perform the requested function or reach the end of the list. This allows your Java application to take advantage of z/OS cryptographic features when they are available, and be able to failover to use another JCE provider that does not rely on these services in the event they are not available.
What does this mean for your Java applications?
- There is no longer a single point of failure
- IBMJCEHYBRID will determine the best provider to use, so you don't have to
- Your Java applications will continue to run even if the hardware crypto services are not available
How to enable IBMJCEHYBRID
Enabling IBMJCEHYBRID is simple. For this demonstration (and the examples in the following sections), I will be using an IBM Semeru Runtime Certified Edition for z/OS, Version 11 JDK.
To enable IBMJCEHYBRID, you must open the java.security file located in <JAVA_HOME>/lib/security/java.security
and edit the security provider list so that IBMJCEHYBRID is the #1 provider in the list (some lines from the java.security file were omitted for conciseness)...
#
# List of providers and their preference orders (see above):
#
security.provider.1=IBMJCEHYBRID
security.provider.2=IBMJCECCA
security.provider.3=OpenJCEPlus
security.provider.4=IBMZSecurity
This will allow Java applications to use IBMJCEHYBRID for all cryptographic requests so that we can have the added benefits discussed in the previous section.
Examples
Now, let's look at two (2) examples: one of a Java application that does not use IBMJCEHYBRID and one that does. I will be using an IBM Semeru Runtime Certified Edition for z/OS, Version 11 JDK.
Sample Java App
For this Java app, we will try to encrypt an AES/GCM/NoPadding Cipher. However, for this example, we will be assuming that ICSF is not started on our mainframe. Here is our Java app that we'll be using...
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class App {
public static void main(String[] args) throws Exception {
String plainText = "Hello from IBM!";
int AES_KEY_SIZE = 256;
int GCM_IV_LENGTH = 12;
int GCM_TAG_LENGTH = 16;
// Create KeyGenerator object
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
// Initialize the key pair generator
keyGenerator.init(AES_KEY_SIZE);
// Generate the secret key
SecretKey key = keyGenerator.generateKey();
// Get a random initialization vector
byte[] IV = new byte[GCM_IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(IV);
// Create a Cipher instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, IV);
// Initialize Cipher for ENCRYPT_MODE
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
// Perform Encryption
byte[] cipherText = cipher.doFinal(plainText.getBytes());
// Print out the cipher text in hex
StringBuilder cipherTextHex = new StringBuilder();
for (byte b : cipherText) {
cipherTextHex.append(String.format("%02x", b));
}
System.out.println("Cipher text: " + cipherTextHex.toString());
}
}
Example 1: Not using IBMJCEHYBRID
Let's configure our java.security file to not include IBMJCEHYBRID. My java.security file now looks like this...
#
# List of providers and their preference orders (see above):
#
security.provider.1=IBMJCECCA
security.provider.2=OpenJCEPlus
security.provider.3=IBMZSecurity
Remember that ICSF is disabled for this example. Let's see what happens when we try to run our Java app with this provider list...
Exception in thread "main" com.ibm.crypto.hdwrCCA.provider.JCECCARuntimeException: Hardware error from call CSNBSYE RC = 12 RSN = 0
at ibm.crypto.hdwrcca/com.ibm.crypto.hdwrCCA.provider.JCEHdwrUtils.d(JCEHdwrUtils.java:1947)
at ibm.crypto.hdwrcca/com.ibm.crypto.hdwrCCA.provider.AESCipher.c(AESCipher.java:2936)
at ibm.crypto.hdwrcca/com.ibm.crypto.hdwrCCA.provider.AESCipher.b(AESCipher.java:1127)
at ibm.crypto.hdwrcca/com.ibm.crypto.hdwrCCA.provider.AESCipher.b(AESCipher.java:837)
at java.base/javax.crypto.Cipher.a(Cipher.java:102)
at App.main(App.java:44)
Since ICSF is not started and IBMJCECCA is the first provider in our list, our program failed because IBMJCECCA tried to use ICSF to perform the AES/GCM cipher encryption, but was not able to communicate with the ICSF service. IBMJCECCA had no choice but to throw an exception indicating that the cipher could not be performed because the underlying hardware was not available.
Example 2: Using IBMJCEHYBRID
Now, let's try running the exact same testcase but instead we'll have IBMJCEHYBRID at the top of the provider list...
#
# List of providers and their preference orders (see above):
#
security.provider.1=IBMJCEHYBRID
security.provider.2=IBMJCECCA
security.provider.3=OpenJCEPlus
security.provider.4=IBMZSecurity
When we run our testcase again, we have a successful run...
Cipher text: 6d9f95b5f6d66b9b3edf6088f01602a2a8c72369c2863c40128a6297bacc22
So what happened? Why did the testcase work once IBMJCEHYBRID was added to the top of our provider list?
When we ran our testcase this time, the JCE framework called upon IBMJCEHYBRID to handle the encryption operation. Now that IBMJCEHYBRID has control, it first tries to recruit IBMJCECCA to perform the cipher because it is the next provider in the list. IBMJCECCA then tries to encrypt the plaintext using ICSF, but ultimately fails because ICSF is not available. IBMJCEHYBRID is notified that IBMJCECCA cannot perform the requested operation because the underlying hardware is disabled. IBMJCEHYBRID then begins it's failover ability by trying to recruit the next available provider to perform the operation instead - in this case it's OpenJCEPlus, another IBM security provider that utilizes hardware crypto, but it's underlying services include GSkit and ICC instead of ICSF.
IBMJCEHYBRID now asks OpenJCEPlus to perform the encryption instead. And since OpenJCEPlus is fully operational and does not rely on ICSF to perform functions, OpenJCEPlus encrypts the plaintext successfully and the program no longer breaks.
Conclusion
In this article, we've learned about the IBMJCEHYBRID security provider and how it can help your Java applications avoid potential issues due to volatile hardware cards and services. Hopefully this will encourage you to try IBMJCEHYBRID in your Java applications as well. Thanks for reading!
Further reading
How to obtain IBMJCEHYBRID
IBMJCEHYBRID is included in the IBM Semeru Runtime Certified Edition for z/OS download. Please follow the links below to download the IBM Semeru JDK onto your own machines.
How to obtain IBM Semeru Runtime Certified Edition for z/OS?
IBM Semeru Runtime Certified Edition for z/OS is available for zero license charge through Shopz SMP/E, or you can download the non-SMP/E here. The subscription and service number is 5655-I48.
Supporting Links:
IBM Semeru Runtime Certified Edition for z/OS product page
For additional information on installation, troubleshooting and support please visit IBM Documentation.