000016002 - BSAFE: Resolve java.lang.SecurityException: java.security.cert.CertificateException: X.509 not found

Document created by RSA Customer Support Employee on Jun 14, 2016Last modified by RSA Customer Support Employee on Apr 21, 2017
Version 2Show Document
  • View in full screen mode

Article Content

Article Number000016002
Applies ToRSA BSAFE SSL-J
RSA BSAFE Cert-J
RSA BSAFE Crypto-J
IssueBSAFE: Resolve java.lang.SecurityException: java.security.cert.CertificateException: X.509 not found

Using the com.rsa.jsafe.provider.JsafeJCE or com.rsa.jsse.JsseProvider provider throws an exception, e.g.

Exception in thread "main" java.lang.ExceptionInInitializerError
...
Caused by: java.lang.SecurityException: java.security.cert.CertificateException: X.509 not found
         at com.rsa.cryptoj.f.ug.d(Unknown Source)
         at com.rsa.cryptoj.f.ug.b(Unknown Source)
         at com.rsa.cryptoj.f.nd.b(Unknown Source)
         at com.rsa.cryptoj.f.nd.c(Unknown Source)
         at com.rsa.jsafe.provider.JsafeJCE.<init>(Unknown Source)

Cause

The JsafeJCE provider requires the vendor's Java provider to be registered earlier in the list.  This is a known problem and there is an open bug to address this (BSFCRYJ-857).  The reason for this is that when going through the JCE API, Crypto-J does runs a JAR verification test, testing its own integrity.  In order to do that, the verification test tries to load up a Sun (or IBM) CA certificate, and this is done again through a JCE call.  Now because the JsafeJCE provider hasn't completed its registration yet, the JCE framework tries to find another provider that can load X.509 certificates and fails if the SUN provider is not registered.

The reason why the X.509 certificate loading goes through the JCE API goes back to Crypto-J 4.0, when there was no X.509 certificate factory available within Crypto-J itself.

Resolution

Register the provider that implements X.509 in the provider list earlier than the JsafeJCE provider.  You can determine the provider by running the code from the Crypto-J sample file JCESample.java, which is called by the JCE samples:


        // Print out a list of the current providers.
        Provider[] currentProviders = Security.getProviders();
        Print.println("Current providers:  ");
        for (int index = 0; index < currentProviders.length; index++) {
            Print.println(currentProviders[index].getName() + " " +
                    currentProviders[index].getVersion());
            Print.println("  " + currentProviders[index].getInfo());
        }


For example, for IBM JDK, the output shows:

IBMCertPath 1.0
  IBMCertPath Provider implements the following:
CertificateFactory                : X.509


So register the com.ibm.security.cert.IBMCertPath provider before the JsafeJCE provider, e.g. in the java.security file (it must be statically registered -- does not work if you dynamically register it in the code):

security.provider.1=com.ibm.security.cert.IBMCertPath
security.provider.2=com.rsa.jsafe.provider.JsafeJCE
security.provider.3=com.rsa.jsse.JsseProvider

Legacy Article IDa56041

Attachments

    Outcomes