根据 JEP 131,Java 8 应该为 64 位 Windows 提供 PKCS#11 Crypto 提供程序: https ://blogs.oracle.com/mullan/entry/jep_131_pkcs_11_crypto 。
考虑到这一点,我使用以下说明下载并使用 NSPR 构建了 32 位和 64 位版本的 NSS: https ://developer.mozilla.org/en-US/docs/NSS_Sources_Building_Testing
我下载了 Java 8 for Windows 64 build b118,配置了 java.security 文件并创建了一个 nss.cfg 文件:
摘自 java.security 文件:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-NSS
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.pkcs11.SunPKCS11 /devel/nss.cfg
nss.cfg:
# Use NSS as a FIPS-140 compliant cryptographic token
# SunPKCS11-NSS
name = NSS
#32 bit
nssLibraryDirectory = C:\devel\nss\nss-3.15.3.1\dist\WINNT6.1_DBG.OBJ\lib
#64 bit
#nssLibraryDirectory = C:\devel\nss\nss-3.15.3.1\dist\WINNT6.1_64_DBG.OBJ\lib
#non FIPS
#nssDbMode = noDb
#attributes = compatibility
#FIPS
nssSecmodDirectory = c:\devel\fipsdb
nssModule = fips
我运行了 NSS 附带的测试套件,看起来所有的加密/解密测试都通过了(在需要主机名/域名的测试中确实存在一些问题,但这与 Windows 环境有关)。
所以这就是问题所在。我使用 32 位版本的 NSS 在 Java 7 32 位上运行我的测试加密应用程序,一切正常。当我尝试使用 64 位 NSS 运行 Java 8 64 位时,出现以下错误:
java.security.ProviderException: Could not initialize NSS
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:212)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jca.ProviderConfig.doLoadProvider(Unknown Source)
at sun.security.jca.ProviderConfig.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getIndex(Unknown Source)
at sun.security.jca.ProviderList.getProviderConfig(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at java.security.Security.getProvider(Unknown Source)
at sun.security.ssl.SunJSSE.<init>(Unknown Source)
at sun.security.ssl.SunJSSE.<init>(Unknown Source)
at com.sun.net.ssl.internal.ssl.Provider.<init>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at sun.security.jca.ProviderConfig$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.jca.ProviderConfig.doLoadProvider(Unknown Source)
at sun.security.jca.ProviderConfig.getProvider(Unknown Source)
at sun.security.jca.ProviderList.getProvider(Unknown Source)
at sun.security.jca.ProviderList$ServiceList.tryGet(Unknown Source)
at sun.security.jca.ProviderList$ServiceList.access$200(Unknown Source)
at sun.security.jca.ProviderList$ServiceList$1.hasNext(Unknown Source)
at javax.crypto.KeyGenerator.nextSpi(KeyGenerator.java:323)
at javax.crypto.KeyGenerator.<init>(KeyGenerator.java:158)
at javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:208)
at STSAESEncryption.generateKeyWithGenerator(STSAESEncryption.java:74)
at Main.main(Main.java:24)
Caused by: java.io.IOException: %1 is not a valid Win32 application.
at sun.security.pkcs11.Secmod.nssLoadLibrary(Native Method)
at sun.security.pkcs11.Secmod.initialize(Secmod.java:210)
at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:207)
... 36 more
我确实向 Sean Mullan 的博客(上面链接)发布了一条消息,并回复了这个问题:一切都在 64 位运行,我无法让它在非 FIPS 模式下工作(同样的错误),但我的回复没有出现在博客上(需要批准)。
有没有其他人试图让 NSS 在 Windows 64 位上使用 Java 8 64 位?
基于 Alex Pakka 评论的更新 1:
感谢您的答复。当我使用 Java 8 64 位时,我使用的是 64 位 NSS 库。在我测试 32 位和 64 位的东西时来回切换。
我附加了代码并逐步完成,但是当我尝试查看 platformPath 变量时,我得到“platformPath 无法解析为变量”。我对 Eclipse 不是很熟悉,所以我想知道我是否做错了什么。
我试图编辑我输入的路径以查看我得到了什么错误,当我将 nssLibraryPath 更改为另一个目录(没有 nss 库)时,我得到一个与 win32 不同的错误。
我确实知道 nss 适用于 Linux(以及可能的其他平台)的 Java 8 64 位,但它是否已针对 Windows 64 位进行了验证。我知道这是 Java 8 和 Windows 64 位的新功能,Java 7 仅支持 Windows 43 位。
再次感谢您的回复,它有所帮助,我仍在努力解决这个问题。