首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android BouncyCastle (SpongyCastle) HTTPS发布请求

Android BouncyCastle (SpongyCastle) HTTPS发布请求
EN

Stack Overflow用户
提问于 2018-03-14 15:40:07
回答 1查看 470关注 0票数 0

我正在尝试用BouncyCastle (SpongyCastle)库登录运行Jellybean4.1.2的旧Android设备上的TLS1.2服务器,但它不起作用。那个版本的Android默认没有启用TLS,所以我需要第三方库来使用它。

有两个问题。1.我得到的是HTTP 302而不是JSON响应。2.我不知道如何发送JSON有效负载(对于我将要使用的其他端点)

对于HTTP 302,我得到以下响应:

代码语言:javascript
复制
Result: HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Cache-Control: private
Expires: Thu, 01 Jan 1970 00:00:00 UTC
Set-Cookie: JSESSIONID=83C535625CDEF9DEC3D7890F1A9C86B0; Path=/; Secure; HttpOnly
Location: https://www.google.com/login/auth                                                               Content-Length: 0
Date: Wed, 14 Mar 2018 15:32:19 GMT
Via: 1.1 google
Set-Cookie: GCLB=CMfzgbfeh7bLpwE; path=/; HttpOnly
Alt-Svc: clear
Connection: close

因此,它似乎试图重定向到某种形式的谷歌登录,这是奇怪的。

另外,在上面的第2条中,我试图发送一个有效负载,我只是添加另一个output.write(myJSONPayload);,还是必须做一些其他的事情?

我的代码如下:

代码语言:javascript
复制
{
    java.security.SecureRandom secureRandom = new java.security.SecureRandom();
    Socket socket = new Socket("www.myserver.com", 443);

    TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), secureRandom);
    DefaultTlsClient client = new DefaultTlsClient() {
        public TlsAuthentication getAuthentication() throws IOException {
            TlsAuthentication auth = new TlsAuthentication() {
                // Capture the server certificate information!
                public void notifyServerCertificate(Certificate serverCertificate) throws IOException {
                }

                public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException {
                    return null;
                }
            };
            return auth;
        }
    };
    protocol.connect(client);

    java.io.OutputStream output = protocol.getOutputStream();
    output.write("GET / HTTP/1.1\r\n".getBytes("UTF-8"));

    //Get auth with my own class to generate base 64 encoding
    output.write(("Authorization: " + BasicAuthentication.getAuthenticationHeader("myuser", "mypass")).getBytes());

    output.write("Host: www.myserver.com/logon\r\n".getBytes("UTF-8"));
    output.write("Connection: close\r\n".getBytes("UTF-8")); // So the server will close socket immediately.
    output.write("\r\n".getBytes("UTF-8")); // HTTP1.1 requirement: last line must be empty line.
    output.flush();

    java.io.InputStream input = protocol.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    String line;
    StringBuilder sb = new StringBuilder();
    try {
        while ((line = reader.readLine()) != null) {
            Log.d(TAG, "--> " + line);
            sb.append(line).append("\n");
        }
    } catch (TlsNoCloseNotifyException e) {
        Log.d(TAG, "End of stream");
    }

    String result = sb.toString();
    Log.d(TAG, "Result: " + result);
}

另一个问题,我是否指定了正确的主机?在Socket中有基本的URL,在OutputStream中有完整的URL,对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-26 15:42:28

这里的解决方案是将此方法添加到我的自定义SSLSocketFactory中:

代码语言:javascript
复制
private static void setupSecurityForTLS() {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        Log.d(TAG, "Adding new security provider");
        Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
        Security.insertProviderAt(new BouncyCastleProvider(), 2);
    }
}

在我初始化套接字之前叫它。

您还可以将这2行添加到类顶部的静态初始化器中,例如:

代码语言:javascript
复制
static {
        Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
        Security.insertProviderAt(new BouncyCastleProvider(), 2);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49281987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档