相关疑难解决方法(0)

如何使用HttpsURLConnection覆盖Android发送到服务器的密码列表?

在TLS协商期间,客户端将支持的密码列表发送到服务器,服务器选择一个密码,然后开始加密.当我HttpsURLConnection用于通信时,我想更改Android发送到服务器的密码列表.

我知道我可以setSSLSocketFactoryHttpsURLConnection对象上使用它来设置它SSLSocketFactory.当我想要更改由SSLSocket返回的信任管理器等时,这非常有用SSLSocketFactory.

我知道一般这个密码组列表可以使用编辑SSLParameters对象,并将其传递到SSlsocketSSLEngine使用他们提供的方法的对象.

SSLSocketFactory似乎没有公开这样的方法!

我找不到一种方法来改变我传递给的创建SSLParameters的返回SSLSocket对象.SSLSocketFactoryHttpsURLConnection

该怎么办?

我想这也与Java有关,不仅仅是Android.也许有一种OO方式来做(例如扩展SSLSocketFactory并提供给它HttpsURLConnection?)

java ssl android jsse httpsurlconnection

11
推荐指数
2
解决办法
1万
查看次数

带有AndroidHttpClient的SSL/TLS协议和密码套件

编辑:道歉,如果我的原始帖子措辞不好.它引起了一些混乱,以对原始帖子的评论为代表.那么让我再试一次:

我开始提问.我想在Android上解决问题,但不知道如何.我花了很多时间在网上寻找解决方案,但在任何地方都找不到关于此问题的单一讨论.尽管如此,包括StackOverflow线程在内的一些讨论让我看到了一种前景看好的技术.我解决了这个问题.但解决方案有点牵扯.所以我决定在这里发布这个问题,思考a)必须有一个更好的解决方案,并希望有人知道并在这里发布答案; 或者b)也许这是一个很好的解决方案,因为我发现网上其他任何地方都没有讨论过这个问题,也许我对这个问题的解决方案对于其他试图做同样事情的人来说也是有用的.无论哪种方式,结果都将是对StackOverflow的新贡献:一个在其他地方无法回答的问题,最终会以某种方式回答正确答案.实际上,StackOverflow甚至邀请我在我最初发布它时通过分享我的知识来回答我自己的问题.事实上,那是我动机的一部分.即使是这件事的事实也没有收集到我找到的任何地方.

所以:

问:当使用AndroidHttpClient通过HTTPS发出REST请求时,如何指定要使用的SSL协议和密码?

这个很重要.很明显,服务器上可以做很多事情,但是有限制.同一台服务器必须提供浏览器,包括旧浏览器以及其他客户端.这意味着服务器必须支持广泛的协议和密码.即使在Android中,如果你必须支持许多不同的版本,你将不得不支持许多不同的协议和密码.

更重要的是,默认情况下,OpenSSL 在SSL握手期间尊重客户端的密码首选项,而不是服务器的密码首选项.例如,请参阅此文章,其中说明您可以通过设置SSL_OP_CIPHER_SERVER_PREFERENCE来覆盖客户端中的该行为.目前还不完全清楚这个选项是否可以在Java中的SSLSocket上设置.即使可以,您也可以自己设置密码列表或告诉客户端尊重服务器列表.否则,您将获得Android默认值,无论您运行的版本是什么(不是您链接的版本).

如果采用默认值,可以在此处看到客户端从Jellybean 4.2+客户端发送到服务器的首选项列表,从第504行开始.默认的协议列表从第620行开始.虽然Jellybean 4.2+包含对OpenSSL的支持1.0.1,特别是TLSv1.1和TLSv1.2,默认情况下不启用这些协议.如果你没有做我做过的事情,你就无法利用TLSv1.2的支持,尽管在最新版本的Android上宣传了对TLSv1.2的支持.回顾以前的Android版本,细节会有很大差异.至少,您可能希望仔细查看所有受支持版本的默认值,并查看客户端实际执行的操作.你可能会感到惊讶.

关于对各种协议和密码的支持,你可以说更多.关键是,有时可能需要在客户端中更改这些设置.

A.使用自定义SSLSocketFactory

这对我来说效果很好,最后,代码并不多.但由于以下几个原因,它有点棘手:

  • 有两种不同的SSLSocketFactory类.客户端需要一个org.apache.http.conn.ssl.SSLSocketFactory,但OpenSSL返回一个javax.net.ssl.SSLSocketFactory.这绝对令人困惑.我使用委托让一个人调用另一个,没有太多问题.
  • 注意OpenSSLContextImpl和SSLContextImpl之间的区别.一个只是包装另一个,但它们不可互换.当我使用SSLContextImpl.engineGetSocketFactory方法时 - 我忘记了究竟发生了什么,但是一些东西悄然失败了.请务必使用OpenSSLContextImpl来获取套接字工厂,而不是SSLContextImpl.您也可以使用javax.net.ssl.SSLSocketFactory.getDefault(),但我不确定.
  • 你不能轻易地将AndroidHttpClient子类化,因为它的构造函数是私有的.这是不幸的,因为它提供了一些其他不错的好东西,比如确保正确关闭它而不是泄漏资源.DefaultHttpClient工作得很好.我从AndroidHttpClient(第105行)借用了newInstance方法.

关键点:

public class SecureSocketFactory extends SSLSocketFactory {
    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        // order should not matter here; the server should select the highest
        // one from this list that it supports
        s.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1" });

        // order matters here; specify in preference order …
Run Code Online (Sandbox Code Playgroud)

java ssl https android openssl

8
推荐指数
1
解决办法
1万
查看次数

Websocket SSL握手失败

我有用于安全websocket连接的spring-boot Tomcat服务器.服务器接受Android 4.4,iOS,Firefox和Chrome客户端,并且没有使用授权签名证书的失败.但是,Android 5.0无法通过SSL握手.

Caused by: javax.net.ssl.SSLHandshakeException: Handshake failed
        at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:436)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1006)
        at org.glassfish.grizzly.ssl.SSLConnectionContext.unwrap(SSLConnectionContext.java:172)
        at org.glassfish.grizzly.ssl.SSLUtils.handshakeUnwrap(SSLUtils.java:263)
        at org.glassfish.grizzly.ssl.SSLBaseFilter.doHandshakeStep(SSLBaseFilter.java:603)
        at org.glassfish.grizzly.ssl.SSLFilter.doHandshakeStep(SSLFilter.java:312)
        at org.glassfish.grizzly.ssl.SSLBaseFilter.doHandshakeStep(SSLBaseFilter.java:552)
        at org.glassfish.grizzly.ssl.SSLBaseFilter.handleRead(SSLBaseFilter.java:273)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:818)
 Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa1f34200: Failure in SSL library, usually a protocol error
error:1408E0F4:SSL routines:SSL3_GET_MESSAGE:unexpected message (external/openssl/ssl/s3_both.c:498 0xac526e61:0x00000000)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake_bio(Native Method)
        at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:423)
Run Code Online (Sandbox Code Playgroud)

我认为问题在于TLS或密码套件由于Android …

ssl grizzly websocket tyrus android-5.0-lollipop

7
推荐指数
1
解决办法
7451
查看次数