如何从Android进行HTTPS POST?

Din*_*ino 15 java ssl https android httpsurlconnection

我想做一个HTTPS post方法,从我的Android应用程序发送一些数据到我的网站.

HttpURLConnection先使用它,我的HTTP URL工作正常.我的生产网站是使用HTTPS的,我希望使用相同的POST发送HttpsURLConnection.有人可以帮我正确使用课程吗?

我在这个链接找到了一些来源:

KeyStore keyStore = ...;    
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");    
tmf.init(keyStore);

SSLContext context = SSLContext.getInstance("TLS");   
context.init(null, tmf.getTrustManagers(), null);

URL url = new URL("https://www.example.com/");   
HttpsURLConnection urlConnection = (HttpsURLConnection)
url.openConnection();   
urlConnection.setSSLSocketFactory(context.getSocketFactory());   
InputStream in = urlConnection.getInputStream();
Run Code Online (Sandbox Code Playgroud)

应该是什么价值 KeyStore keyStore = ...;

我尝试使用相同的方式发送数据 HttpURLConnection,但我看到一些POST数据丢失或出错.

我试过这个问题的方法.我在下面粘贴我的代码

String urlParameters="dateTime=" + URLEncoder.encode(dateTime,"UTF-8")+
    "&mobileNum="+URLEncoder.encode(mobileNum,"UTF-8");

URL url = new URL(myurl);
HttpsURLConnection conn;
conn=(HttpsURLConnection)url.openConnection();

// Create the SSL connection
SSLContext sc;
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setConnectTimeout(HTTP_CONNECT_TIME_OUT);
conn.setReadTimeout(HTTP_READ_TIME_OUT);

//set the output to true, indicating you are outputting(uploading) POST data
conn.setDoOutput(true);
//once you set the output to true, you don't really need to set the request method to post, but I'm doing it anyway
conn.setRequestMethod("POST");
conn.setFixedLengthStreamingMode(urlParameters.getBytes().length);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(urlParameters);
out.close();

InputStream is = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
  response += inputLine;            
}                   
Run Code Online (Sandbox Code Playgroud)

我得到的错误如下:

05-12 19:36:10.758: W/System.err(1123): java.io.FileNotFoundException: https://www.myurl.com/fms/test
05-12 19:36:10.758: W/System.err(1123):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
05-12 19:36:10.758: W/System.err(1123):     at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:270)
05-12 19:36:10.758: W/System.err(1123):     at .httpRequest(SMSToDBService.java:490)
05-12 19:36:10.758: W/System.err(1123):     at com..access$0(SMSToDBService.java:424)
05-12 19:36:10.758: W/System.err(1123):     at com.$ChildThread$1.handleMessage(SMSToDBService.java:182)
05-12 19:36:10.758: W/System.err(1123):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-12 19:36:10.758: W/System.err(1123):     at android.os.Looper.loop(Looper.java:156)
05-12 19:36:10.758: W/System.err(1123):     at com.$ChildThread.run(SMSToDBService.java:303)
Run Code Online (Sandbox Code Playgroud)

tbk*_*n23 18

您可以使用Android设备中定义的默认CA,这对任何公共网络都适用.

如果您有自签名证书,您可以接受所有证书(有风险,对中间人攻击开放)或创建自己的证书TrustManagerFactory,这有点超出此范围.

以下是使用默认CA进行https POST调用的一些代码:

private InputStream getInputStream(String urlStr, String user, String password) throws IOException
{
    URL url = new URL(urlStr);
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

    // Create the SSL connection
    SSLContext sc;
    sc = SSLContext.getInstance("TLS");
    sc.init(null, null, new java.security.SecureRandom());
    conn.setSSLSocketFactory(sc.getSocketFactory());

    // Use this if you need SSL authentication
    String userpass = user + ":" + password;
    String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
    conn.setRequestProperty("Authorization", basicAuth);

    // set Timeout and method
    conn.setReadTimeout(7000);
    conn.setConnectTimeout(7000);
    conn.setRequestMethod("POST");
    conn.setDoInput(true);

    // Add any data you wish to post here

    conn.connect();
    return conn.getInputStream();
}   
Run Code Online (Sandbox Code Playgroud)

阅读回复:

        String result = new String();
        InputStream is = getInputStream(urlStr, user, password);
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            result += inputLine;            
        }       
Run Code Online (Sandbox Code Playgroud)


小智 5

这是一个Android HttpsUrlConnection POST 解决方案,包含证书固定、超时服务器端代码和配置。

该变量的params格式应为 username=demo&password=abc123&。

@Override
public String sendHttpRequest(String params) {
    String result = "";
    try {
        URL url = new URL(AUTHENTICATION_SERVER_ADDRESS);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(KeyPinStore.getInstance().getContext().getSocketFactory()); // Tell the URLConnection to use a SocketFactory from our SSLContext
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(10000);
        PrintWriter out = new PrintWriter(connection.getOutputStream());
        out.println(params);
        out.close();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()), 8192);
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            result = result.concat(inputLine);
        }
        in.close();
        //} catch (IOException e) {
    } catch (IOException | KeyStoreException | CertificateException | KeyManagementException | NoSuchAlgorithmException e) {
        result = e.toString();
        e.printStackTrace();
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)