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.
August 17th, 2009 at 21:01
[...] “JAVA Security Provider Error” from Marc on getting the proper security provider when porting an application from JBoss to [...]
August 19th, 2009 at 03:01
[...] “JAVA Security Provider Error” [...]
August 19th, 2009 at 09:01
[...] “JAVA 安全性提供者错误” 来自 Marc,将应用程序从 JBoss 传输到 GlassFish 时获得合适的安全提供者。 [...]
August 26th, 2009 at 12:05
[...] I googled up for this exception, I found this which is the case when Ciphers are loaded in the [...]
September 9th, 2009 at 16:21
Hi! I was surfing and found your blog post… nice! I love your blog.
Cheers! Sandra. R.
September 17th, 2010 at 16:20
Hi Marc,
Thanks for putting up the solution for the Cipher Issue ,Was quite useful for us in our environment
Best Regards
April 5th, 2011 at 14:06
Thanks for posting this. You saved me!!