JAVA Security Provider Error
... 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());
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:
After that all worked well. A very trivial issue to resolve, however annoying nonetheless.