在JAVA中发出HTTPS请求并打开SSL套接字

在JAVA中发出HTTPS请求并打开SSL套接字,ssl,https,javafx,Ssl,Https,Javafx,我正在尝试建立一个登录页面。为此,我想打开一个SSL套接字并发出一个HTTPS请求,但我得到了未知主机异常-- SSLSocket skt=(SSLSocket)sslsf.createSocket(“https://31.21.18.222/room_info/x.txt" , 443); 有人能告诉我我做错了什么吗?另外,我已经关闭了主机验证,因为我的程序中不需要它 `public void clickLogin() throws IOException, CertificateExcep

我正在尝试建立一个登录页面。为此,我想打开一个SSL套接字并发出一个HTTPS请求,但我得到了未知主机异常-- SSLSocket skt=(SSLSocket)sslsf.createSocket(“https://31.21.18.222/room_info/x.txt" , 443); 有人能告诉我我做错了什么吗?另外,我已经关闭了主机验证,因为我的程序中不需要它

`public void clickLogin() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {


            URL url = new URL ("https://31.21.18.222/room_info/x.txt");
            HttpsURLConnection connection = null;
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);        //Make an empty store
            InputStream fis = new FileInputStream("C:/Documents and Settings/user/Desktop/PK/localhost.crt"); 
            BufferedInputStream bis = new BufferedInputStream(fis);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            while (bis.available() > 0) {
                java.security.cert.Certificate cert = cf.generateCertificate(bis);
                keyStore.setCertificateEntry("localhost", cert);
            }

            // write code for turning off client verification
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
            tmf.init(keyStore);
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, tmf.getTrustManagers() , null);
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            SSLSocketFactory sslsf = context.getSocketFactory();
            SSLSocket skt = (SSLSocket)sslsf.createSocket("https://31.21.18.222/room_info/x.txt" , 443);
            skt.setUseClientMode(true);
            SSLSession s = skt.getSession(); // handshake implicitly done
            skt.setKeepAlive(true);


            connection = (HttpsURLConnection) url.openConnection();

        // Host name verification off
            connection.setHostnameVerifier(new HostnameVerifier()  
            {        
                public boolean verify(String hostname, SSLSession session)  
                {  
                    return true;  
                }  
            });  `

如果要使用
createSocket
打开套接字,则需要使用主机名(或IP地址),而不是完整的URL:

example : sslsf.createSocket("31.21.18.222" , 443);
此外:

  • 不要使用
    Security.addProvider(新的com.sun.net.ssl.internal.ssl.Provider())
    (默认情况下它在那里)
  • 使用
    TrustManagerFactory tmf=TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
    而不是
    X.509
    ,可能更好,特别是因为tmf的默认算法是
    PKIX
    ,而不是
    X.509
  • createSocket
    将根据信任锚验证证书,但不会检查主机名(这也是防止MITM攻击所必需的)。为此,通常最好使用主机名而不是IP地址

顺便说一句,您为什么要直接使用
HttpsUrlConnection
SSLSocket
呢?+1是一个很好的解释。Joe Roth,如果你能通过接受“如果这对你有帮助”来奖励它,那就太好了。我打赌是这样:)