Java8无法在FIPS中加载其cacerts。例外情况;没有此类供应商:SunEC“;

Java8无法在FIPS中加载其cacerts。例外情况;没有此类供应商:SunEC“;,java,java-8,fips,pkcs#11,nss,Java,Java 8,Fips,Pkcs#11,Nss,我的服务器使用Java7,在FIPS模式下运行良好。现在我们正在升级到jre8,在加载cacerts的启动过程中出现以下异常 java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96) at sun.security.util.ECUtil.deco

我的服务器使用Java7,在FIPS模式下运行良好。现在我们正在升级到jre8,在加载cacerts的启动过程中出现以下异常

java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
   at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
   at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
   at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
   at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
   at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
   at sun.security.x509.X509Key.parse(X509Key.java:170)
   at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
   at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
   at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
   at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
   at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
   at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
   at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
   at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
   at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
   at java.security.KeyStore.load(KeyStore.java:1433)
   at org.apache.commons.ssl.KeyStoreBuilder.tryJKS(KeyStoreBuilder.java:476)
   at org.apache.commons.ssl.KeyStoreBuilder.parse(KeyStoreBuilder.java:383)
   at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:212)
   at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:165)
   at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:170)
   at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:175)
   at org.apache.commons.ssl.TrustMaterial.<clinit>(TrustMaterial.java:88)
   at org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:317)
Caused by: java.security.NoSuchProviderException: no such provider: SunEC
        at sun.security.jca.GetInstance.getService(GetInstance.java:83)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
        at java.security.KeyFactory.getInstance(KeyFactory.java:211)
        at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
java.lang.RuntimeException:java.security.NoSuchProviderException:没有这样的提供程序:SunEC
位于sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
位于sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
位于sun.security.pkcs11.P11ECKeyFactory.EngineeGeneratePublic(P11ECKeyFactory.java:170)
位于java.security.KeyFactory.generatePublic(KeyFactory.java:334)
位于sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
位于sun.security.x509.X509Key.parse(X509Key.java:170)
位于sun.security.x509.CertificateX509Key。(CertificateX509Key.java:75)
位于sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
位于sun.security.x509.X509CertInfo。(X509CertInfo.java:167)
位于sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
位于sun.security.x509.X509CertImpl.(X509CertImpl.java:195)
位于sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
位于java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
位于sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
位于sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
加载(KeyStore.java:1433)
位于org.apache.commons.ssl.keystrebuilder.tryJKS(keystrebuilder.java:476)
位于org.apache.commons.ssl.keystrebuilder.parse(keystrebuilder.java:383)
位于org.apache.commons.ssl.TrustMaterial(TrustMaterial.java:212)
在org.apache.commons.ssl.TrustMaterial上(TrustMaterial.java:165)
位于org.apache.commons.ssl.TrustMaterial(TrustMaterial.java:170)
位于org.apache.commons.ssl.TrustMaterial(TrustMaterial.java:175)
位于org.apache.commons.ssl.TrustMaterial(TrustMaterial.java:88)
位于org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:317)
原因:java.security.NoSuchProviderException:无此类提供程序:SunEC
位于sun.security.jca.GetInstance.getService(GetInstance.java:83)
位于sun.security.jca.GetInstance.GetInstance(GetInstance.java:206)
位于java.security.KeyFactory.getInstance(KeyFactory.java:211)
位于sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
我所做的唯一修改是将TLSv1.2添加到jdk.tls.disabledAlgorithms=SSLv3,TLSv1.2,因为NSS不支持TLSv1.2

我能够在jre7u72构建中加载相同的内容,并且看到sunpkcs11.jar在Java8中被修改。这不应该是一个cacerts问题,因为我将java7 cacerts复制到java8,问题仍然存在

以前有人见过这个问题吗?它应该是java bug吗

==编辑===

打开了一个Java8错误。我编写了一个工具,它成功地运行在jre7上,但在jre8上失败了

 import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.KeyStore;
    import java.security.Provider;
    import java.security.Security;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    import sun.security.provider.Sun;
    import sun.security.rsa.SunRsaSign;

/**
 * Before running the tool run the following in your Linux box.
 * 
    1. export LD_LIBRARY_PATH=/usr/lib64
    2. mkdir /tmp/fips/nssdb
    3. modutil -create -dbdir /tmp/fips/nssdb/
    4. modutil -fips true -dbdir /tmp/fips/nssdb
    5. modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /tmp/fips/nssdb
      (Give a strong password like password1!)

 * @author atulsm@gmail.com
 *
 */
    public class TestKeyStoreFIPS {

        public static final String NSS_LIB_DIR_PROP = "nss.lib";
        public static final String NSS_DB_DIR_PROP = "nss.db";
        public static final String SUN_JSSE = "SunJSSE";
        public static List<String> disabledAlgs = new ArrayList<String>();

        private static final Logger logger = Logger.getLogger(TestKeyStoreFIPS.class.getName());

        /**
         * @param args
         */
        public static void main(String[] args) throws Exception{
            if(args.length != 2){
                System.out.println("Usage eg: java -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb  -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit");
                System.exit(1);
            }

            enablePkcs11Jsse(System.getProperty(NSS_LIB_DIR_PROP), System.getProperty(NSS_DB_DIR_PROP));
            testFips();

            String file = args[0];
            char[] keystorePassword = args[1].toCharArray();
            FileInputStream keystoreStream = new FileInputStream(file);

            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(keystoreStream, keystorePassword);

            Enumeration<String> aliases = keyStore.aliases();

            while(aliases.hasMoreElements()){
                String alias = aliases.nextElement();
                System.out.println(alias + " : " + keyStore.getCertificate(alias).getType());

            }

        }

        private static void testFips(){
            String keyPass = System.getProperty("javax.net.ssl.keyStorePassword");      
            KeyStore store;

            try {
                store = KeyStore.getInstance("PKCS11");
                if (keyPass != null) {
                    store.load(null, keyPass.toCharArray());
                } else {
                    store.load(null, null);
                }
                System.out.println("FIPS test success");
            } catch (Throwable e) {
                e.printStackTrace();
                store = null;
                System.out.println("FIPS test failed");
            }                       
        }


        public static void enablePkcs11Jsse( String libDir, String dbDir) throws Exception {
            removeAllProviders();

            Provider nss = getNSSFIPSProvider( libDir, dbDir);
            removeDisabledAlgos(nss);       
            Security.insertProviderAt(nss, 1);

            Provider sunJsse = new com.sun.net.ssl.internal.ssl.Provider(nss);
            removeDisabledAlgos(sunJsse);
            Security.insertProviderAt(sunJsse,2);

            Sun sun = new Sun();
            removeDisabledAlgos(sun);       
            Security.insertProviderAt(sun,3);

            SunRsaSign sunrsa = new SunRsaSign();
            removeDisabledAlgos(sunrsa);
            Security.insertProviderAt(sunrsa,4);
        }   


       private static Provider getNSSFIPSProvider( String libDir, String dbDir) throws Exception {

           if(libDir == null || dbDir == null) {
               throw new Exception(NSS_LIB_DIR_PROP + " or " + NSS_DB_DIR_PROP + " not set.");
           }

           Properties props = new Properties();
           props.put("name", "NSSfips");
           props.put("nssLibraryDirectory", libDir);
           props.put("nssSecmodDirectory", dbDir);
           props.put("nssModule", "fips");
           props.put("nssDbMode", "readWrite");

           return createProvider(props);
       }

       private static Provider createProvider(Properties props) throws IOException {
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           props.store(out, null);
           ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

           Provider ret = new sun.security.pkcs11.SunPKCS11(in);
           if (logger.isLoggable(Level.FINE)) {
               // Log all of the registered services
               for (Map.Entry<Object, Object> entry : ret.entrySet()) {
                   logger.log(Level.FINE, "{0} = {1}", new Object[]{entry.getKey(), entry.getValue()});
               }
           }
           return ret;
       }

       private static void removeAllProviders(){    
        Provider[] providers = Security.getProviders();
        for(Provider prov : providers){
            Security.removeProvider(prov.getName());
        }
       }

        private static void removeDisabledAlgos(Provider provider){     
            for(String alg : disabledAlgs){
                if(provider.getProperty(alg) != null){
                    logger.info("Removing algorithm " + alg + " from provider " + provider);
                    provider.remove(alg);
                }
            }
        }   

    }
import java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.security.KeyStore;
导入java.security.Provider;
导入java.security.security;
导入java.util.ArrayList;
导入java.util.Enumeration;
导入java.util.List;
导入java.util.Map;
导入java.util.Properties;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入sun.security.provider.sun;
导入sun.security.rsa.SunRsaSign;
/**
*在运行该工具之前,请在Linux框中运行以下命令。
* 
1.导出LD_LIBRARY_PATH=/usr/lib64
2.mkdir/tmp/fips/nssdb
3.modutil-create-dbdir/tmp/fips/nssdb/
4.modutil-fips true-dbdir/tmp/fips/nssdb
5.modutil-更改PW“NSS FIPS 140-2证书数据库”-dbdir/tmp/FIPS/nssdb
(请输入密码1之类的强密码!)
*@作者atulsm@gmail.com
*
*/
公共类测试密钥{
公共静态最终字符串NSS\u LIB\u DIR\u PROP=“NSS.LIB”;
公共静态最终字符串NSS\u DB\u DIR\u PROP=“NSS.DB”;
公共静态最终字符串SUN_JSSE=“SunJSSE”;
public static List disabledAlgs=new ArrayList();
私有静态最终记录器Logger=Logger.getLogger(testkeystrefips.class.getName());
/**
*@param args
*/
公共静态void main(字符串[]args)引发异常{
如果(参数长度!=2){
System.out.println(“用法如:java-Dnss.lib=/usr/lib64-Dnss.db=/tmp/fips/nssdb-Djavax.net.ssl.keystrepassword=password1!TestKeyStoreFIPS/tmp/jre8/lib/security/cacerts changeit”);
系统出口(1);
}
enablePkcs11Jsse(System.getProperty(NSS_LIB_DIR_PROP)、System.getProperty(NSS_DB_DIR_PROP));
testFips();
字符串文件=args[0];
char[]keystorePassword=args[1]。toCharArray();
FileInputStream keystrestream=新的FileInputStream(文件);
KeyStore KeyStore=KeyStore.getInstance(“JKS”);
加载(keystoream,keystorePassword);
枚举别名=keyStore.alias();
while(别名.hasMoreElements()){
字符串别名=别名。nextElement();
System.out.println(别名+”:“+keyStore.getCertificate(别名).getType());
}
}
私有静态void testFips(){
字符串keyPass=System.getProperty(“javax.net.ssl.keystrepassword”);
密钥存储;
试一试{
store=KeyStore.getInstance(“PKCS11”);
if(keyPass!=null){
load(null,keyPass.toCharArray());
}否则{
store.load(null,null);
}
System.out.println(“FIPS测试成功”);
}捕获(可丢弃的e){
e、 printStackTrace();
store=null;
System.out.println(“FIPS t