We recently made the switch from 32-bit to 64-bit java. Our project uses the SunMSCAPI provider to retrieve certificates from the Windows personal keystore in order to perform mutual authentication and request/response signing. The moment we switched from a 32-bit JVM (1.6.0_18) to a 64-bit JVM of the same update version, some of our crypto functionality stopped working. After much digging, here is what I have discovered.
The JVM seems incapable of locating the Windows-MY keystore, I suspect because no keystore of that name has been registered.
java.security.NoSuchAlgorithmException: Windows-MY KeyStore not available
The 32-bit distributions of Java 6 SDK (updates 17 and 18) contain the following files:
and a java.security policy file which contains the line: security.provider.9=sun.security.mscapi.SunMSCAPI
The 64-bit distributions of the Java 6 SDK (updates 17 and 18) do not contain sunmscapi.dll, or sunmscapi.jar, and the java.security policy file DOES NOT contain a registration for the sunmscapi provider.
I've scanned all of the JCA and JSE documentation I can find. Nothing makes mention of the lack of a SunMSCAPI provider in 64-bit versions. No document I can find explains whether this functionality has been folded into another provider. Has someone else made the 32-bit to 64-bit switch and overcome this issue?
Have you tried copying the 32-bit DLLs to the 64-bit environment and adding the entry into java.security to see what result you get? I have to believe that 64-bit Windows does support calling 32-bit libraries in some "legacy" mode (as Solaris and Linux operating systems do). You might have to place the 32-bit DLLs in some special directory reserved for 32-bit applications - that's how Linux deals with 64-bit and 32-bit libraries.
MCorrFleet, arshad.noor, Thank you for the swift replies.
Unfortunately there is no method of loading 32-bit DLLs into a 64-bit process on Windows Vista x64. (I'm a Mac/Linux person, so that assertion is based on google, not personal knowledge). The purported work-around is to use a surrogate process and pass information between the two processes using an architecture-neutral IPC channel (I suppose that's sort of a tautology. Is there an architecture-dependent IPC channel?)
We may end up having to write our own provider. Our project can't go back to 32-bit Java because of memory requirements.
A few other options you might want to consider. I'm assuming your keys are on some smartcard or other hardware module which only has a CAPI-based CSP for access. If you're using just the file-based keystore in Windows, you may as well just export the keys to a PKCS12 file and access it directly from your Java application.
The IPC channel is one option - but IMHO it only adds another layer of indirection - a bridge to a bridge - leading to a bridge too far? :-) - and can only increase support headaches.
You might want to consider compiling the Java source in 64-bit mode and see if gets you anywhere: [http://download.java.net/jdk6/source/|http://download.java.net/jdk6/source/] . Sometimes, some modules don't get delivered because critical resources are not available for testing/documentation/whatever. You may find that building your own 64-bit DLL will be a more reliable short-term solution until Sun/Oracle releases a 64-bit DLL with their distribution
Another option - see if the JDK7 distribution ( [http://download.java.net/jdk7/|http://download.java.net/jdk7/]) has 64-bit DLLs and copy them and see if they work with JDK6. Or, maybe you can go to JDK7 directly even though it is EA, if it works for you.
The final answer on this is that Sun have accepted my bug report for this missing, omitted, or not yet implemented feature.
The IPC solution is indeed a bridge too far. The source is available, but licensing issues and customer constraints might prevent us from recompiling it. Fortunately, we were only using the Windows keystore for ease of customer key management. We can deal with the file-based keystores at the expense of deployment and maintenance headaches.
I've finally come back to this problem and found a reasonable solution. It appears that acquiring the source for sunmscapi.dll and compiling it in Visual C++ yields a functioning sunmscapi.dll. We're back to using the Windows keystore on our project.
I'm very disappointed in Sun for shipping the Windows x64 JVM in this condition.
I know it is a rather old and inactive thread but I was unable to find more recent information on the subject.
If you still keep information how you did the compilation of sunmscapi.dll using x64 Windows and share it here will be great. I spent several hours trying to find precompiled x64 dll or instructions how to recompile just sumscapi.dll without luck.
I have already downloaded the Open JDK, but it seems that recompiling the whole JDK will take considerable amount of efforts. That is why I was hoping that recompiling just this dll will be enough.