java.security.NoSuchAlgorithmException: X509 KeyManagerFactory 不可用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36170406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:01:58  来源:igfitidea点击:

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available

javasslcryptography

提问by sudhanshu

I want to create SSL connection. I created keystore. and trying to use x509.

我想创建 SSL 连接。我创建了密钥库。并尝试使用 x509。

 final KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");

but I am getting below exception on console after running.

但我在运行后在控制台上遇到异常。

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available at sun.security.jca.GetInstance.getInstance(Unknown Source) at javax.net.ssl.KeyManagerFactory.getInstance(Unknown Source) SSLContext sc = SSLContext.getInstance(connectionType); final char[] keyPassPhrase = "changeit".toCharArray(); //String [] array = Security.getProviders(); final KeyStore ks = KeyStore.getInstance("jks");

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory 在 javax.net.ssl.KeyManagerFactory.getInstance(Unknown Source) 的 sun.security.jca.GetInstance.getInstance(Unknown Source) 不可用 SSLContext sc = SSLContext.getInstance(connectionType); final char[] keyPassPhrase = "changeit".toCharArray(); //String [] array = Security.getProviders(); 最终 KeyStore ks = KeyStore.getInstance("jks");

        ks.load(new FileInputStream("ClientKeyStore"), keyPassPhrase);
        provider();
        final KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); // this line is problem

        // SunX509 : supporting only: [TLSv1, TLSv1.1, TLSv1.2]
        kmf.init(ks, keyPassPhrase);

        sc.init(kmf.getKeyManagers(), new TrustManager[] {
                new X509TrustManager(){
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    @Override
                    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException {

                    }
                    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                            throws CertificateException {
                    }
                }
        },new SecureRandom());
        SSLSocketFactory factory = sc.getSocketFactory();
        SSLSocket socket=null;
        try{
            //socket = (SSLSocket) factory.createSocket("XXXX",xxxx);/
            socket = (SSLSocket) factory.createSocket(ipAddress, Integer.parseInt(ports[portIndex]));

            //convert to array
            String[] cipherSelectedArray;
            if(isSupported == 1 ) {
                cipherSelectedArray = new String[] {msupportedcipherList.get(cipherIndex).trim()};
            }
            else {
                cipherSelectedArray = new String[] {mnotSupportedcipherList.get(cipherIndex).trim()};
            }

            String []mselectedSSLOrTLSVersionArrray = new String[] {mselectedSSLOrTLSVersion};   // if passing these --> getting connection timeout

            socket.setEnabledProtocols(mselectedSSLOrTLSVersionArrray);
            socket.setEnabledCipherSuites(cipherSelectedArray);
            for(int i = 0; i<cipherSelectedArray.length ; i++) {
                //System.out.println("ciphers are :" +  cipherSelectedArray[i]);
            }


            socket.setSoTimeout(15000);

            socket.addHandshakeCompletedListener(new HandshakeCompletedListener() {

                @Override
                public void handshakeCompleted(HandshakeCompletedEvent event) {
                    ////System.out.println("completed");

                }
            });



            socket.startHandshake(); //handshake                                            as "SunX509" does not support SSL. I need to create above one. Can someone help.   And also with "SunX509" i am getting                                              java.lang.IllegalArgumentException: Cannot support TLS_RSA_WITH_AES_256_CBC_SHA with currently installed providers problem with some ciphers. please help

回答by Saif

The parameter you are using X509is not recognized by the algorithm provider.

X509算法提供程序无法识别您正在使用的参数。

As described getInstance(String algorithm)the reason is clear.

正如所描述的getInstance(String algorithm)原因很清楚。

NoSuchAlgorithmException - if no Provider supports a KeyManagerFactorySpi implementation for the specified algorithm.

NoSuchAlgorithmException - 如果没有提供程序支持指定算法的 KeyManagerFactorySpi 实现。

The standard algorithms are described here

这里描述标准算法

I guess they support PKIX, SunX509this two algorithm in KeyManagerFactory

我猜他们支持 PKIX, SunX509这两种算法KeyManagerFactory

So you have to use SunX509instead of X509.

所以你必须使用SunX509而不是X509.

See the table here

请参阅此处的表格

回答by Tim Biegeleisen

Read what the stack trace is telling you:

阅读堆栈跟踪告诉您的内容:

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory 不可用

The X509algorithm is not available from the security provider you are using. However, the following code should work for you:

X509您使用的安全提供程序不提供该算法。但是,以下代码应该适合您:

final KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

Please have a look at this Code Ranch articlewhich discusses your problem and also shows how to find out which security algorithms are available from your provider.

请查看这篇Code Ranch 文章,其中讨论了您的问题,并展示了如何找出您的提供商提供的安全算法。

回答by user23288

The problem with the use of "SunX509" is that it is specific for an Oracle JRE and doesn't work in an IBM JRE, where the default is "IbmX509". A better solution which is vendor-agnostic is:

使用“SunX509”的问题在于它特定于 Oracle JRE,不适用于 IBM JRE,其中默认值为“IbmX509”。与供应商无关的更好解决方案是:

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

The default algorithm is defined by the security property "ssl.keyManagerFactory.algorithm" in <JRE_HOME>/lib/security/java.security, and is by default "SunX509" in Oracle and "IbmX509" in IBM JREs (at least for Java 8).

默认算法由 中的安全属性“ssl.keyManagerFactory.algorithm”定义,<JRE_HOME>/lib/security/java.security在 Oracle 中默认为“SunX509”,在 IBM JRE 中默认为“IbmX509”(至少对于 Java 8)。