Skip to main content

 
IBM Systems  > Mainframe servers  > Operating systems  > 

Java Security

(last updated October, 2004)

  
dblue_rule.gif
A Practical Look at z/OS-specific Java Security Exploitation   grey_rule.gif

Hardware cryptography using IBMJCE4758

Setup

  • Requires ICSF installation and initiation
  • Remember to activate hardware
  • The IBMJCE4758 provider needs to be added to the provider list either statically in the file ${java-home}/lib/security/java.security
security.provider.1=com.ibm.crypto.hdwrCCA.provider.IBMJCE4758
security.provider.2=com.ibm.crypto.provider.IBMJCE
...
or adding the provider at run time
Security.insertProviderAt(
    new com.ibm.crypto.hdwrCCA.provider.IBMJCE4758(), 1);

Policy files

  • Full Function versus Limited Key Size Cryptography
  • Default: US_export_policy.jar and local_policy.jar pre-installed in directory ${java-home}/lib/security: limited function cryptography with no export restrictions
  • Download unrestricted policy files
  • Replace files US_export_policy.jar and local_policy.jar in the ${java-home}/lib/security: full function cryptography
  • also available in ${java-home}/demo/jce/policy-files

Symmetric key generation, encrypt/decrypt

/* The Java framework APIs are used to generate a DES key. */
KeyGenerator desKeyGen = KeyGenerator.getInstance("DES", 
   "IBMJCE4758");
SecretKey key = desKeyGen.generateKey();

/* The piece of data that we are going to encrypt/decrypt 
   sign/verify. */
byte[] plaintext = "This is a test message to play 
   with".getBytes();

/* Using the DES key previously generated we can encrypt then 
   decrypt a piece of data. */
Cipher cp = Cipher.getInstance("DES", "IBMJCE4758");
cp.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cp.doFinal(plainText);
cp.init(Cipher.DECRYPT_MODE, key, cp.getParameters());
byte[] newPlainText = cp.doFinal(cipherText);
Back to Samples
Back to top

Key generation - asymmetric key

/*
The Java framework APIs of java are used to generate a
JCE4758 hardware RSA key pair. We can then obtain the public
key and private key of the key pair.
*/
KeyPairGenerator rsaKeyPairGen =
    KeyPairGenerator.getInstance("RSA","IBMJCE4758");
RSAKeyParameterSpec keySpec = new RSAKeyParameterSpec(1024,
    KeyHWAttributeValues.CLEAR,
    KeyHWAttributeValues.KEYMANAGEMENT);
rsaKeyPairGen.initialize(keySpec);
KeyPair rsaKeyPair = rsaKeyPairGen.generateKeyPair();
PublicKey rsaPub = rsaKeyPair.getPublic();
PrivateKey rsaPriv = rsaKeyPair.getPrivate();
Back to Samples
Back to top

Sign and verify

/*
Using the RSA key pair that we previously generated we can 
sign a piece of data with the private key then verify that 
same piece of data using the public key.
*/
Signature sig = Signature.getInstance
  ("SHA1withRSA", "IBMJCE4758");
sig.initSign(rsaPriv);
sig.update(plainText);
byte[] signature = sig.sign();
sig.initVerify(rsaPub);
sig.update(plainText);
boolean result = sig.verify(signature);
Back to Samples
Back to top

Using keys from a keystore

/* Load the keystore from a given file. */
KeyStore keyStore = KeyStore.getInstance("JCE4758KS");
char[] storepass = "storepass".toCharArray();
char[] keypass = "keypass".toCharArray();
FileInputStream storeStream = 
  new FileInputStream("jce4758store");
  keyStore.load(storeStream, storepass);

/*
Get the private and public keys of "mykey". A key
entry in a keystore contains the private key and the 
certificate or certificate chain associated with it. 
We can get our certificate by calling 
KeyStore.getCertificate() for an alias that
identifies a key entry.
*/
PrivateKey privKey = 
  (PrivateKey)keyStore.getKey("mykey", keypass);
Certificate cert = keyStore.getCertificate("mykey");
PublicKey pubKey = cert.getPublicKey();
Back to Samples
Back to top

Creating a key with hwkeytool

hwkeytool -genkey \
          -keyalg RSA \
          -keysize 1024 \
          -sigalg MD5withRSA \
          -validity 365 \
          -alias mykey \
          -dname "CN=IBM User, O=IBM, C=US" \
          -storetype jce4758ks \
          -storepass storepw \
          -keypass keypw \
          -keystore ~/.HWkeystore \
          -keylabel keylbl \
          -hardwareusage KEYMANAGEMENT \
          -hardwaretype CLEAR \
          -provider com.ibm.crypto.hdwrCCA.provider.
             IBMJCE4758 \
          -v
Back to top

grey_rule.gif

Use of SAF key rings with Java

Setup

  • In order to use SAF certificates for trust or key information, IBMCertPath provider needs to be in the java.security provider list or added at runtime. For example:
Security.addProvider(new com.ibm.security.cert.IBMCertPath());
Back to top

JCE4758RACFKS sample

/* Get certificates and keys from RACF */
RACFInputStream ksStream = 
  new RACFInputStream("userid", "hwring", null);
KeyStore keyStore = 
  KeyStore.getInstance("JCE4758RACFKS");
  keyStore.load(ksStream, null);

/* Get the private and public key associated with the 
   specified alias */
Key privKey = keyStore.getKey("hwkey", null);
PublicKey pubKey = 
  keyStore.getCertificate("hwkey").getPublicKey();
Back to Samples
Back to top

JCERACFKS sample

/* Get certificates and keys from RACF */
RACFInputStream ksStream = 
  new RACFInputStream("userid", "aring", null);
KeyStore keyStore = 
  KeyStore.getInstance("JCERACFKS");
  keyStore.load(ksStream, null);

/* Get the private and public key associated with the 
   specified alias */
Key privKey = keyStore.getKey("akey", null);
PublicKey pubKey = 
  keyStore.getCertificate("akey").getPublicKey();
Back to Samples
Back to top

Listing a JCERACFKS keystore with keytool

keytool -list \
        -storetype JCERACFKS \
        -keystore safkeyring:///aring \
        -J-Djava.protocol.handler.pkgs=com.ibm.crypto.
            provider
Back to top

Listing a JCE4758RACFKS keystore with hwkeytool

hwkeytool -list \
          -storetype JCE4758RACFKS \
          -keystore safkeyring:///hwring \
          -J-Djava.protocol.handler.pkgs=
           com.ibm.crypto.hdwrCCA.provider
Back to top

grey_rule.gif

z/OS unique features for the IBMJSSE provider

IBMJSSE Setup Issues

  • The IBMJSSE provider must be in your java.security provider list or added at runtime in your code. For example:
  • Security.addProvider(new com.ibm.jsse.IBMJSSEProvider());
    
  • You will need the IBMCertPath provider in your java.security provider list or added at runtime if you wish to use SAF certificates for trust or key information
  • You will need the IBMJCE4758 provider in your java.security provider list or added at runtime if you wish to use hardware acceleration with the IBMJSSE provider.
Back to top

IBMJSSE using SAF key rings

Initializing SSL context

/*
Create the RACFInputStream that gives us access to a 
particular SAF key ring. In this case use userid 
"" to access the key ring
"ServerKeyring" and use the password "passphrase" to 
protect the in memory representation of the RACF 
key ring.
*/
KeyStore ks = KeyStore.getInstance("JCERACFKS");
com.ibm.crypto.provider.RACFInputStream inputStream =
    new com.ibm.crypto.provider.RACFInputStream
      ("",
       "ServerKeyring",
       "passphrase".toCharArray());
ks.load(inputStream, "passphrase".toCharArray());

/* Initialize the key manager */
KeyManagerFactory kmf = 
  KeyManagerFactory.getInstance("IbmX509");
kmf.init(ks, "passphrase".toCharArray());

/* Initialize the trust manager */
TrustManagerFactory tmf = 
  TrustManagerFactory.getInstance("IbmX509");
tmf.init(ks);

/* Initialize the SSL context */
sslContext = (SSLContext)SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), 
tmf.getTrustManagers(), null);
Back to Samples
Back to top

Getting an SSL session (server)

/* Get and print the list of supported enabled 
   cipher suites */
String enabled[] = 
  sslContext.getSocketFactory().getSupportedCipherSuites();
for (i=0; i < enabled.length; i++)
    System.out.println(enabled[i]);

/* Create an SSL session over port 8070 */
SSLServerSocketFactory factory = 
  sslContext.getServerSocketFactory();
SSLServerSocket ssl_server_sock =
    (SSLServerSocket)factory.createServerSocket(8070);
SSLSocket ssl_sock;

ssl_sock = (SSLSocket)(ssl_server_sock.accept());
ssl_sock.setEnabledCipherSuites(enabled);

ssl_sock.startHandshake();
SSLSession session = ssl_sock.getSession();
System.out.println("\nServerJsse: SSL 
  connection established");
System.out.println("   cipher suite:       " 
  + session.getCipherSuite());
Back to Samples
Back to top

IBMJSSE using IBMJCE4758

Initializing SSL context

/*
Initialize the KeyManagerFactory using the IBMJCE4758 
provider as the provider for crypto operations
*/
KeyStore ks = KeyStore.getInstance("JCE4758KS");
ks.load(new FileInputStream("testkeys.4758"), 
"passphrase".toCharArray());
KeyManagerFactory kmf = 
  KeyManagerFactory.getInstance("IbmX509");
KeyManagerFactoryParametersSpec parms =
new KeyManagerFactoryParametersSpec (ks,
                           "passphrase".toCharArray(),
                           "IBMJCE4758");
kmf.init(parms);

/* Initialize the trust manager */
TrustManagerFactory tmf = 
  TrustManagerFactory.getInstance("IbmX509");
tmf.init(ks);

/* Initialize the SSL context */
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), 
  tmf.getTrustManagers(), null);
Back to Samples
Back to top

Getting an SSL session (server)

/* Create an SSL session over port 8070 */
SSLServerSocketFactory factory = 
  sslContext.getServerSocketFactory();
SSLServerSocket ssl_server_sock =
    (SSLServerSocket)factory.createServerSocket(8070);
SSLSocket ssl_sock;
ssl_sock = (SSLSocket)(ssl_server_sock.accept());
ssl_sock.setEnabledCipherSuites(enabled); 

ssl_sock.startHandshake();
SSLSession session = ssl_sock.getSession();
System.out.println("\nServerJsse4758Provider: 
  SSL connection established");
System.out.println("   cipher suite:       " 
  + session.getCipherSuite());
Back to Samples
Back to top

IBMJSSE using the URL handler

Initializing SSL context

/*
Add the URL handler to the handler property. This
informs IBMJSSE what URL handler to use to handle 
the safkeyring support. In this case IBMJCE.
*/
System.setProperty("java.protocol.handler.pkgs",
"com.ibm.crypto.provider");

/*
Set the system properties which say what keystore
to use for IBMJSSE's key information. The key store
contains the end user personal certificates that are
used in the authentication process.
*/
System.setProperty("javax.net.ssl.keyStore",
    "safkeyring:///ServerKeyring");
System.setProperty("javax.net.ssl.keyStoreType", 
                   "JCERACFKS");
System.setProperty("javax.net.ssl.keyStorePassword", 
                   "password");

/* Initialize the key manager */
KeyManagerFactory kmf = KeyManagerFactory.getInstance
                  ("IbmX509");
KeyStore ks = null;
kmf.init(ks, null);

/*
Set the system properties which say what truststore
to use for JSSE's trust information. The trust store 
contains the CA certificates that are used in the 
authentication process.
*/
System.setProperty("javax.net.ssl.trustStore",
    "safkeyring://userid/ServerKeyring");
System.setProperty("javax.net.ssl.trustStoreType", 
                   "JCERACFKS");
System.setProperty("javax.net.ssl.trustStorePassword", 
                   "password"); 

/* Initialize the trust manager */
TrustManagerFactory tmf = TrustManagerFactory.getInstance
                  ("IbmX509");
tmf.init(ks);

/* Initialize the SSL context */
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), 
                tmf.getTrustManagers(), null);
Back to Samples
Back to top

Getting an SSL session (server)

/* Create an SSL session over port 8050 */
SSLServerSocketFactory factory = 
  sslContext.getServerSocketFactory();
SSLServerSocket ssl_server_sock =
(SSLServerSocket)factory.createServerSocket(8050);
SSLSocket ssl_sock;

ssl_sock = (SSLSocket)(ssl_server_sock.accept());
ssl_sock.setEnabledCipherSuites(enabled);

ssl_sock.startHandshake();
SSLSession session = ssl_sock.getSession();
System.out.println("\nServerJsse: SSL connection 
                   established");
System.out.println("   cipher suite:       " 
  + session.getCipherSuite());
Back to Samples
Back to top

grey_rule.gif

Miscellaneous Topics

Creating a SAF key ring in RACF

/* REXX */
ADDRESS TSO

/* Delete all the certificates. */
"RACDCERT DELETE (LABEL('hwkey'))"
"RACDCERT DELETE (LABEL('cacert'))"

/* Delete the key ring. */
"RACDCERT DELRING(hwring)"

/* Creating a key ring. */
"RACDCERT ADDRING(hwring)"

/* Generating the certificates */
"RACDCERT GENCERT SUBJECTSDN(CN('Trusted Certificate') 
          C('US')) " || ,
          "WITHLABEL('cacert') TRUST ICSF"

"RACDCERT GENCERT SUBJECTSDN(CN('PK hwkey') O('IBM')) " || ,
          "WITHLABEL('hwkey') SIGNWITH(LABEL('cacert')) ICSF"

/* Connecting Certificates to their key rings */
"RACDCERT CONNECT (LABEL('cacert') RING(hwring) 
           USAGE(CERTAUTH))"
"RACDCERT CONNECT (LABEL('hwkey') RING(hwring) DEFAULT 
           USAGE(PERSONAL))"

/* Facility class refresh */
"SETROPTS RACLIST(FACILITY) REFRESH"

/* List the key ring */
"RACDCERT LISTRING(hwring)"
Back to top

grey_rule.gif

Appendix A: Samples

These are working code samples that may be used without royalty or license. They are provided as-is.

Samples

Back to top


 

suncup.gif