JAVA Security Provider Error

Just a quick note about a simple but annoying error I encountered when porting an app to glassfish; The code in question was as follows:

 
     ... 
    Charset charset = Charset.forName("UTF-8");
    CharsetEncoder encoder = charset.newEncoder();
    ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(str));
    SecretKeySpec key = new SecretKeySpec( KEY_BASE, "DES" );

    private static Cipher ecipher = Cipher.getInstance( "DES");
    ecipher.init( Cipher.ENCRYPT_MODE, key ); 
    byte[] enc = ecipher.doFinal( bbuf.array() );
     ...
The code above just converts a string (stored as str here) to UTF-8 then encrypts it using DES. Equivalently you could use str.getBytes() for the UTF conversion. The code above worked fine on JBOSS, and worked fine stand alone. It even worked on my glassfish test server, however when deployed on glassfish enterprise I started getting the following stacktrace:
    java.security.ProviderException: update() failed
        at  sun.security.pkcs11.P11Cipher.implUpdate(P11Cipher.java:557)
        at  sun.security.pkcs11.P11Cipher.engineUpdate(P11Cipher.java:457)
        at  sun.security.pkcs11.P11Cipher.engineDoFinal(P11Cipher.java:485)
        at  sun.security.pkcs11.P11Cipher.engineDoFinal(P11Cipher.java:471)
        at  javax.crypto.Cipher.doFinal(DashoA13*..)
    ...
    Caused  by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DEVICE_ERROR
        at  sun.security.pkcs11.wrapper.PKCS11.C_EncryptUpdate(Native Method)
        at  sun.security.pkcs11.P11Cipher.implUpdate(P11Cipher.java:510)

After much trial and error I found the issue at hand was caused by the security provider being used. Adding the following code segment I output the provider being used and ran it both stand alone and inside glassfish:

            System.out.println("--------" + ecipher.getProvider().getName());
            System.out.println(ecipher.getProvider().getInfo());
            System.out.println(ecipher.getProvider().getVersion()) System.out.println("--------" + ecipher.getProvider().getName());
    System.out.println(ecipher.getProvider().getName());
    System.out.println(ecipher.getProvider().getInfo());
    System.out.println(ecipher.getProvider().getVersion());

When running stand alone I got the following output:

SunJCE
SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, 
                 ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
1.6

Running in glassfish I got:

SunPKCS11-__SUN_SJSAS_internal
SunPKCS11-__SUN_SJSAS_internal using library C:\Sun\AppServer\lib\softokn3.dll

I tried prioritizing SunJCE in java.security however the above results did not change. Finally I just specified SunJCE in my Cipher.getInstance so:

Cipher.getInstance("DES", "SunJCE");

After that all worked well. A very trivial issue to resolve, however annoying nonetheless.


7 Responses to “JAVA Security Provider Error”

Leave a Reply