如何使用android将HTTPS请求发送到自签名cartificate FLASK服务器?

如何使用android将HTTPS请求发送到自签名cartificate FLASK服务器?,android,https,Android,Https,我使用openSSL制作了一个带有以下cmd的证书: openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 并在FLASK服务器上使用证书和密钥运行 if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, ssl_context=('cert.pem', 'key.pem')) 我观察到,在接受警告后,使用浏

我使用openSSL制作了一个带有以下cmd的证书:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
并在FLASK服务器上使用证书和密钥运行

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, ssl_context=('cert.pem', 'key.pem'))
我观察到,在接受警告后,使用浏览器\邮递员,我可以访问服务器,但是

有关FLASK服务器和证书的更多信息,请参阅

如何向我的FLASK服务器发送POST\GET请求?

默认情况下,Android支持“真实”证书(允许将其加密为其中之一)。不幸的是,当服务器不是在域上而是在IP上运行时,不支持“真正的”CA提供程序

使用自签名服务器时,可以向客户端提供自签名CA(而不是密钥!)将CA添加到已知CA中。我不是一个安全专家,但中间人攻击的方式是不可能的。 1.将.pem转换为.crt-android不支持
.pen
,而是
.crt

openssl x509 -outform der -in cert.pem  -out cert.crt

并将新的
cert.crt
移动到android项目中的资产文件夹中

  • 在客户端代码中:
  • SslUtils类直接从这里获取

    (这里的示例扩展了AsyncTask-用于学习android中使用async的http:)

    protected String doInBackground(String... strings) {
            Log.i(TAG, "doInBackground started" );
            HttpsURLConnection urlConnection = null;
            try {
                String urlString = strings[0];
                URL url = new URL(urlString);
                urlConnection = (HttpsURLConnection) url.openConnection();
                // adding the ca
                SSLContext sslContext= SslUtils.getSslContextForCertificateFile("cert.crt",context);
                urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
                // additional settings
                urlConnection.setRequestProperty("Content-Type", "application/json");
                urlConnection.setRequestMethod("POST");
                urlConnection.setDoOutput(true);
                urlConnection.setDoInput(true);
                urlConnection.setChunkedStreamingMode(0);
                // match CA host name to the url 
                urlConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                       //allowedHosted is a pre-defined list with the allowed host names as strings
                       for (String allowHost : allowedHostes){
                           if (allowHost.equals(hostname)) {
                               return true;
                           }
                       }
                       return false;
                    }
                });
    
                int code = urlConnection.getResponseCode();
                if (code !=  200) {
                    throw new IOException("Invalid response from server: " + code);
                }
    
                // normal code to continue....