GVKun编程网logo

如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?(如何调用https接口)

3

如果您对如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于如何设置用于使用HttpsURLCo

如果您对如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?的详细内容,我们还将为您解答如何调用https接口的相关问题,并且为您提供关于Android学习之使用HTTP协议访问网络之HttpURLConnection、Android:使用HttpsURLConnection的HTTPS(SSL)连接、https HttpsURLConnection 请求的单向认证、https 用 HttpsURLConnectio如何登陆 post方式的有价值信息。

本文目录一览:

如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?(如何调用https接口)

如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?(如何调用https接口)

正常的方式来获得的SSLSocketFactory将是初始化一个新的SSLContextTrustManagerKeyManagerSecureRandom和使用getSocketFactory()方法。但是,这不允许我启用所需的密码套件或协议。

唯一HttpsURLConnection允许进行此类更改的配置是通过设置其默认值SSLSocketFactory。我可以创建一个类来扩展SSLSocketFactory和覆盖getDefaultCipherSuites()方法,并包装创建的套接字createSocket()以设置所需的密码和协议。但是,此方法不允许我TrustManager为连接初始化a
吗?

有没有我可以同时做的方法-设置密码套件和协议并初始化信任管理器?

答案1

小编典典

SSLSocketFactory获取的取为SSLContext.getSocketFactory()并将其包装在的自定义子类中SSLSocketFactory,该子类委托从获取的自类SSLContext,但createSocket()还设置了所需的密码。

Android学习之使用HTTP协议访问网络之HttpURLConnection

Android学习之使用HTTP协议访问网络之HttpURLConnection

#转自第一行代码—郭霖
首先new出一个URL对象,传入目标对象的网络地址,再new一个HttpURLConnection的实例,然后调用URL的openConnection()方法即可。如下代码所示:

 URL url = new URL("https://www.baidu.com/");
 HttpURLConnection connection = null;
 connection = (HttpURLConnection) url.openConnection();

在得到HttpURLConnection的实例后,我们设置HTTP请求使用 GET 还是 POST。

GET希望从服务器获取数据
POST希望提交数据给服务器
connection.setRequestMethod("GET");//从服务器获取数据

接下来可设置一些参数,常用的有设置连接超时,设置读取超时的毫秒数等等:

connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);

接着调用getInputStream()方法可以获取到服务器返回的输入流,然后就是对输入流进行读取,如下:

InputStream in = connection.getInputStream();

最后调用disconnect()方法将这个HTTP连接关闭掉

connection.disconnect();

具体代码实现
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/sendRequestBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/send_request"/>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/responseText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </ScrollView>
</LinearLayout>

MainActivity.java

package com.example.lbstest;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.BufferUnderflowException;

public class MainActivity extends AppCompatActivity {
    private Button sendRequestBtn;
    private TextView responseText;
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sendRequestBtn = findViewById(R.id.sendRequestBtn);
        responseText = findViewById(R.id.responseText);
        sendRequestBtn.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendRequestWithHttpURLConnection();
            }
        });
    }
    private void sendRequestWithHttpURLConnection(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL("https://www.baidu.com/");
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream in = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder reponse = new StringBuilder();
                    String line;
                    while((line = reader.readLine()) != null){
                        reponse.append(line);
                    }
                    showResponse(reponse.toString());

                } catch (MalformedURLException | ProtocolException e) {
                    e.printstacktrace();
                } catch (IOException e) {
                    e.printstacktrace();
                }finally {
                    if (reader != null){
                        try {
                            reader.close();
                        }catch (IOException e){
                            e.printstacktrace();
                        }
                    }
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    private void showResponse(final String response) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                responseText.setText(response);
            }
        });
    }

}

Android:使用HttpsURLConnection的HTTPS(SSL)连接

Android:使用HttpsURLConnection的HTTPS(SSL)连接

我有2个应用程序,一个是Servlet / Tomcat服务器,另一个是Android应用程序。

我想使用HttpURLConnection在两者之间发送和接收XML。

码:

    private String sendPostRequest(String requeststring) {

    DataInputStream dis = null;
    StringBuffer messagebuffer = new StringBuffer();

    HttpURLConnection urlConnection = null;

    try {
        URL url = new URL(this.getServerURL());

        urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.setDoOutput(true);

        urlConnection.setRequestMethod("POST");

        OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());

        out.write(requeststring.getBytes());

        out.flush();

        InputStream in = new BufferedInputStream(urlConnection.getInputStream());

        dis = new DataInputStream(in);

        int ch;

        long len = urlConnection.getContentLength();

        if (len != -1) {

            for (int i = 0; i < len; i++)

                if ((ch = dis.read()) != -1) {

                    messagebuffer.append((char) ch);
                }
        } else {

            while ((ch = dis.read()) != -1)
                messagebuffer.append((char) ch);
        }

        dis.close();

    } catch (Exception e) {

        e.printStackTrace();

    } finally {

        urlConnection.disconnect();
    }

    return messagebuffer.toString();
}

现在,我需要使用SSL来发送XML以确保安全。

首先,我使用Java Keytool生成.keystore文件。

Keytool  -keygen -alias tomcat -keyalg RSA

然后我将XML代码放在Tomcat的server.xml文件中以使用SSL

<Connector 
port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="c:/Documents and Settings/MyUser/.keystore"
keystorePass="password"
clientAuth="false" sslProtocol="TLS" 
/>

然后,将其更改为HttpsURLConnection的HttpURLConnection

    private String sendPostRequest(String requeststring) {

    DataInputStream dis = null;
    StringBuffer messagebuffer = new StringBuffer();

    HttpURLConnection urlConnection = null;

    //Conexion por HTTPS
    HttpsURLConnection urlHttpsConnection = null;

    try {
        URL url = new URL(this.getServerURL());

        //urlConnection = (HttpURLConnection) url.openConnection();

        //Si necesito usar HTTPS
        if (url.getProtocol().toLowerCase().equals("https")) {

            trustAllHosts();

            //Creo la Conexion
            urlHttpsConnection = (HttpsURLConnection) url.openConnection();

            //Seteo la verificacion para que NO verifique nada!!
            urlHttpsConnection.setHostnameVerifier(DO_NOT_VERIFY);

            //Asigno a la otra variable para usar simpre la mism
            urlConnection = urlHttpsConnection;

        } else {

            urlConnection = (HttpURLConnection) url.openConnection();
        }

//Do the same like up

并添加trustAllHosts方法以信任每个服务器(不要检查任何证书)

private static void trustAllHosts() {

    X509TrustManager easyTrustManager = new X509TrustManager() {

        public void checkClientTrusted(
                X509Certificate[] chain,String authType) throws CertificateException {
            // Oh,I am easy!
        }

        public void checkServerTrusted(
                X509Certificate[] chain,I am easy!
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

    };

    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null,trustAllCerts,new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    } catch (Exception e) {
            e.printStackTrace();
    }
}

这些更改效果很好,但是我不想信任每台服务器。我想使用我的密钥库文件来验证连接并以正确的方式使用SSL。我在互联网上阅读了很多书,做了很多测试,但是我不明白我必须做些什么以及如何做。

有人可以帮我吗?

非常感谢你

对不起,我英语不好

-------------------------更新2011/08/24 -------------------

好吧,我还在努力。我做了一个新方法来设置KeyStore,InputStream等

该方法如下所示:

private static void trustIFNetServer() {

    try {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

        KeyStore ks = KeyStore.getInstance("BKS");

        InputStream in = context.getResources().openRawResource(R.raw.mykeystore);

        String keyPassword = "password";

        ks.load(in,keyPassword.toCharArray());

        in.close();

        tmf.init(ks);

        TrustManager[] tms = tmf.getTrustManagers();

        SSLContext sc = SSLContext.getInstance("TLS");

    sc.init(null,tms,new java.security.SecureRandom());

    } catch (Exception e) {
    e.printStackTrace();
    }
}

首先,我在密钥和证书方面遇到很多问题,但现在可以正常工作了(我认为是这样)

我现在的问题是超时异常。我不知道为什么会生成。我认为这与数据写入有关,但是我还无法解决。

任何想法?

https HttpsURLConnection 请求的单向认证

https HttpsURLConnection 请求的单向认证

参考链接

android httpClient (https/http) 的优化构建方式一

android httpClient (https/http) 的优化构建方式二

Java https 请求 HttpsURLConnection

php 使用 curl 库进行 ssl 双向认证

OpenSSL 生成根证书 CA 及签发子证书

Java 使用 SSLSocket 通信

android 让 webview 支持 https 双向认证 (SSL)(一)

android 让 webview 支持 https 双向认证 (SSL)(二)

webview 的自定义 SSL 认证配置(p12 证书)

 

Https 访问的相关知识中,主要分为单项验证和双向验证,双向验证在单项验证的基础上构建而成

 

关于单项验证,如果要细分的话,分为证书验证和普通验证(忽略验证),因为这项验证针对客户端,所以客户端有能力控制是否需要验证

 

忽略验证的方式

主要如下继承 X509TrustManager 和 HostnameVerifier

public class SSLTrustManager implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager ,HostnameVerifier{
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
  
        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
  
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
         
            @Override
        public boolean verify(String urlHostName, SSLSession session) //允许所有主机
            return true;
        }
        
   //封装
public static HttpURLConnection connect(String strUrl) throws Exception {
         
         javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
         javax.net.ssl.TrustManager tm = new SSLTrustManager();
         trustAllCerts[0] = tm;
         javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                 .getInstance("SSL");
         sc.init(null, trustAllCerts, null);
         javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
                 .getSocketFactory());
          
         HttpsURLConnection.setDefaultHostnameVerifier((HostnameVerifier) tm);
          
        URL url = new URL(strUrl);
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
      
        return urlConn;
    }
        
 }

双向证书验证方式

如下,这里采用双向验证

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class HttpsPost {
    /**
     * 获得KeyStore.
     * @param keyStorePath
     *            密钥库路径
     * @param password
     *            密码
     * @return 密钥库
     * @throws Exception
     */
    public static KeyStore getKeyStore(String password, String keyStorePath)
            throws Exception {
        // 实例化密钥库
        KeyStore ks = KeyStore.getInstance("JKS");
        // 获得密钥库文件流
        FileInputStream is = new FileInputStream(keyStorePath);
        // 加载密钥库
        ks.load(is, password.toCharArray());
        // 关闭密钥库文件流
        is.close();
        return ks;
    }

    /**
     * 获得SSLSocketFactory.
     * @param password
     *            密码
     * @param keyStorePath
     *            密钥库路径
     * @param trustStorePath
     *            信任库路径
     * @return SSLSocketFactory
     * @throws Exception
     */
    public static SSLContext getSSLContext(String password,
            String keyStorePath, String trustStorePath) throws Exception {
        // 实例化密钥库
        KeyManagerFactory keyManagerFactory = KeyManagerFactory
                .getInstance(KeyManagerFactory.getDefaultAlgorithm());
        // 获得密钥库
        KeyStore keyStore = getKeyStore(password, keyStorePath);
        // 初始化密钥工厂
        keyManagerFactory.init(keyStore, password.toCharArray());

        // 实例化信任库
        TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 获得信任库
        KeyStore trustStore = getKeyStore(password, trustStorePath);
        // 初始化信任库
        trustManagerFactory.init(trustStore);
        // 实例化SSL上下文
        SSLContext ctx = SSLContext.getInstance("TLS");
        // 初始化SSL上下文
        ctx.init(keyManagerFactory.getKeyManagers(),
                trustManagerFactory.getTrustManagers(), null);
        // 获得SSLSocketFactory
        return ctx;
    }

    /**
     * 初始化HttpsURLConnection.
     * @param password
     *            密码
     * @param keyStorePath
     *            密钥库路径
     * @param trustStorePath
     *            信任库路径
     * @throws Exception
     */
    public static void initHttpsURLConnection(String password,
            String keyStorePath, String trustStorePath) throws Exception {
        // 声明SSL上下文
        SSLContext sslContext = null;
        // 实例化主机名验证接口
        HostnameVerifier hnv = new MyHostnameVerifier();
        try {
            sslContext = getSSLContext(password, keyStorePath, trustStorePath);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        if (sslContext != null) {
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
                    .getSocketFactory());
        }
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
    }

    /**
     * 发送请求.
     * @param httpsUrl
     *            请求的地址
     * @param xmlStr
     *            请求的数据
     */
    public static void post(String httpsUrl, String xmlStr) {
        HttpsURLConnection urlCon = null;
        try {
            urlCon = (HttpsURLConnection) (new URL(httpsUrl)).openConnection();
            urlCon.setDoInput(true);
            urlCon.setDoOutput(true);
            urlCon.setRequestMethod("POST");
            urlCon.setRequestProperty("Content-Length",
                    String.valueOf(xmlStr.getBytes().length));
            urlCon.setUseCaches(false);
            //设置为gbk可以解决服务器接收时读取的数据中文乱码问题
            urlCon.getOutputStream().write(xmlStr.getBytes("gbk"));
            urlCon.getOutputStream().flush();
            urlCon.getOutputStream().close();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    urlCon.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试方法.
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 密码
        String password = "123456";
        // 密钥库
        String keyStorePath = "tomcat.keystore";
        // 信任库
        String trustStorePath = "tomcat.keystore";
        // 本地起的https服务
        String httpsUrl = "https://localhost:8443/service/httpsPost";
        // 传输文本
        String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><fruitShop><fruits><fruit><kind>萝卜</kind></fruit><fruit><kind>菠萝</kind></fruit></fruits></fruitShop>";
        HttpsPost.initHttpsURLConnection(password, keyStorePath, trustStorePath);
        // 发起请求
        HttpsPost.post(httpsUrl, xmlStr);
    }
}

单向证书验证

public static KeyStore getHttpsKeyStore()
	{
	    InputStream ins = null;
	    try {
	    	
	    	    ins = new FileInputStream("srca.cer"); 
	            //读取证书
	            CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");  //问1
	            Certificate cer = cerFactory.generateCertificate(ins);
	            //创建一个证书库,并将证书导入证书库
	            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());   //问2
	            keyStore.load(nullnull);
	            keyStore.setCertificateEntry("trust", cer);
	            return keyStore;
	    } catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(ins!=null)
			{
	            try {
					ins.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	    }
	    return null;
	}
public void initSSLContext()
{
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
        trustManagerFactory.init(getHttpsKeyStore());
        sslContext.init( null, trustManagerFactory.getTrustManagers(), new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
                    
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
       
        @Override
        public boolean verify(String hostname, SSLSession sslsession) {
      
        if("localhost".equals(hostname)){  
            return true;  
        } else {  
            return false;  
        }  
      }
  });
}

https 用 HttpsURLConnectio如何登陆 post方式

https 用 HttpsURLConnectio如何登陆 post方式

不是进入登陆页面,而是通过用户 名称和密码,进入到系统欢迎页面。

今天的关于如何设置用于使用HttpsURLConnection创建的套接字的密码和协议列表?如何调用https接口的分享已经结束,谢谢您的关注,如果想了解更多关于Android学习之使用HTTP协议访问网络之HttpURLConnection、Android:使用HttpsURLConnection的HTTPS(SSL)连接、https HttpsURLConnection 请求的单向认证、https 用 HttpsURLConnectio如何登陆 post方式的相关知识,请在本站进行查询。

本文标签: