关于ssl:java.security.NoSuchAlgorithmException:X509 KeyManagerFactory不可用

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available

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

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

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

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");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
        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

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

如getInstance(String algorithm)所述,原因很明显。

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

这里描述了标准算法

我猜他们在KeyManagerFactory中支持PKIX, SunX509这两个算法

因此,您必须使用SunX509而不是X509

见这里的表


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

java.security.NoSuchAlgorithmException: X509 KeyManagerFactory not available

X509算法无法从您使用的安全提供程序中获得。但是,以下代码应为您工作:

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

请查看此代码牧场文章,该文章讨论了您的问题,还显示了如何找出可从提供商处获得的安全算法。


使用" SunX509"的问题是它特定于Oracle JRE,并且在IBM JRE(默认值为" IbmX509")中不起作用。一个与供应商无关的更好的解决方案是:

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

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