I am getting the following exception when I try to open JCEKS type key store with with Oracle Java 8 JRE 172 on Windows. This worked fine with earlier versions of the JRE:
INFO: ObjectInputFilter REJECTED: null, array length: -1, nRefs: 1, depth: 1, bytes: 70, ex: n/a
[...call stacks omitted to protect the innocent...]
Caused by: java.io.IOException: Invalid secret key format
at com.sun.crypto.provider.JceKeyStore.engineLoad(JceKeyStore.java:856)
at java.security.KeyStore.load(Unknown Source)
[...]
This looks very much like JDK-8202506 but I use Java 8 and I get null
in the initial INFO message.
Is this the same issue?
It seems to me the JDK-8202506 issue is currently not fixed in any public JRE release. Am I right?
UPDATE 1
This looks similar and they also have no solution: ATLAS-2642
UPDATE 2
For some reason, Equinox fails to see the com.sun.crypto.provider.SealedObjectForKeyProtector
class after the upgrade, even though it is clearly in the JRE that comes with the new JDK:
BundleClassLoader[foo.bar.baz.crypto].loadClass(com.sun.crypto.provider.SealedObjectForKeyProtector) failed.
java.lang.ClassNotFoundException: com.sun.crypto.provider.SealedObjectForKeyProtector
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:481)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:397)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:385)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:87)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:686)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2040)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at com.sun.crypto.provider.JceKeyStore.engineLoad(JceKeyStore.java:850)
at java.security.KeyStore.load(KeyStore.java:1445)
UPDATE 3
The class SealedObjectForKeyProtector.class
is somehow different from the rest of the classes in the sunjce_provider.jar
. When we try to decompile it with JD-GUI, it fails with internal error, unlike the rest of the classes:
I meet this issue these days. And per my troubleshooting, it is caused by the different return value of this method:
sun.misc.VM.latestUserDefinedLoader()
Previously (before 8u171), this method returns sun.misc.Launcher$ExtClassLoader
, while it returns application's classloader after upgrade. In ObjectInputStream, both class loader can load com.sun.crypto.provider.SealedObjectForKeyProtector
successfully, that's simply because ExtClassLoader is the parent of application's class loader (or, parent's parent). However, once SealedObjectForKeyProtector is loaded by application's class loader, it's class loader no longer equals to ExtClassLoader.
On the other hand, within com.sun.crypto.provider.JceKeyStore
, unlike ObjectInputStream
, SealedObjectForKeyProtector
is always loaded by ExtClassLoader. Thus below check in JceKeyStore.java:932 will fail due to class doesn't equal:
932 if (info.serialClass() != SealedObjectForKeyProtector.class))
934 return Status.REJECTED;
Then, we will get below log and an IOException eventually:
ObjectInputFilter
REJECTED: class com.sun.crypto.provider.SealedObjectForKeyProtector
Solution: make sure class com.sun.crypto.provider.SealedObjectForKeyProtector
is not loaded by ContextClassLoader by certain configuration. Details depend on the ContextClassLoader. For example, for org.powermock.core.classloader.MockClassLoader
, the concrete solution is adding below annotation to involved test classes:
@PowerMockIgnore("com.sun.*")