小编Jim*_*Dee的帖子

带有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万
查看次数

如何以编程方式枚举iOS资产目录中的所有图像集?

我想列出iOS 7.x SDK中应用程序资产目录中可用的所有图像集.我想我可以遍历应用程序包中的文件夹,但我没有看到另一种方式.有没有更好的办法?

assets ios7

6
推荐指数
0
解决办法
293
查看次数

在使用VBOS时,如何将法线向量信息传输到OpenGL ES 2.0?

更新:似乎大部分内容现已消失.我认为在OpenGL ES 2.0中正确进行照明的方法是编写自己的着色器,以任何方式传递法线,然后在着色器中进行照明.特别是,根据OpenGL ES 2.0文档,不再有glMaterialFv,glLightFv等.(更不用说glNormalPointer和朋友了.)我认为这是为我编译的原因是因为这些东西是由iOS提供的GLKit,虽然显然他们没有真正开箱即用的替代品.但是,GLKit提供了一些标准着色器来模仿OpenGL ES 1.1中的照明功能.

如果有人有任何进一步的信息,我很感激,但我认为这就是答案.


我是OpenGL的新手,所以提前为任何混乱道歉.我在iOS上使用OpenGL ES 2.0.我在互联网上找到的许多例子似乎已经过时了.例如,glBegin(GL_POLYGON)方法似乎已被弃用,因此我认为我不能使用glNormal3f,正如大多数旧例子所做的那样.

我从Ray Wenderlich的漂亮教程开始,并将其与我正在构建的游戏集成,成功渲染了一些房间的基本几何形状.现在我只想添加灯光.我不确定什么不起作用,但我怀疑它与法线有关.

我做了一个混乱的尝试来启用GL_LIGHT0,主要来自OpenGL 文档.

//* Some attempts at lighting
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light0_position[] = { 0.0, 0.0, 7.99, 0.0 };
GLfloat light0_ambience[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambience);
glLightfv(GL_LIGHT0, GL_SPECULAR, …
Run Code Online (Sandbox Code Playgroud)

opengl-es-2.0

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

标签 统计

android ×1

assets ×1

https ×1

ios7 ×1

java ×1

opengl-es-2.0 ×1

openssl ×1

ssl ×1