AndroidHttpClient需要更多信息自签名SSL可能?

如何解决AndroidHttpClient需要更多信息自签名SSL可能?

| 关于androidhttpclient的信息很少,特别是我找不到任何好的示例。根据我的阅读-我可以使用此客户端,并且已为SSL进行了预配置。我的目标是2.2+,因此对我来说效果很好。 有什么好的用法示例吗?专门用于REST服务POST 是否有关于如何允许自签名证书的示例?我不介意只允许任何证书,而不是将特定证书导入本地存储。 谢谢! 我自己的答案(请参见下面的代码)。 我有带有自签名证书的IIS服务器。我必须采取额外的步骤并生成与外部名称而不是服务器名称匹配的证书。 我使用androidhttpclient。据说,此客户端具有android的所有\“ proper \”设置,并且从版本8开始受支持 我在Application对象中创建androidhttpclient并共享。 我在注入自定义证书的地方分离了代码,因此以后可以轻松删除它。我注意到,从资源加载证书确实需要花时间在App启动上。 我的应用程序单例版本。请参阅顶部的注释,以及我用来生成所有内容的命令行的详细信息。在整个过程中使用相同的密码以确保其有效。 PKS文件密码必须匹配。
import android.net.http.androidhttpclient;
import android.app.Application;
import android.util.Log;
import idatt.mobile.android.providers.DBLog;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;

import java.io.InputStream;
import java.security.KeyStore;

/*
To generate PKS:
1. Created cert in IIS7 and then exported as pfx. Follow instruction on SelfSSL: http://www.robbagby.com/iis/self-signed-certificates-on-iis-7-the-easy-way-and-the-most-effective-way/
1a. Download tool: http://cid-3c8d41bb553e84f5.skydrive.live.com/browse.aspx/SelfSSL
1b. Run: SelfSSL /N:CN=mydomainname /V:1000 /S:1 /P:8081
 I use port 8081 on my server
1c. Export from IIS manager to cert.pfx
2. Run command line in SSL to convert file into X.509:
openssl pkcs12 -in C:\\cert.pfx -out C:\\cert.cer -nodes
3. Edit file and delete all except -----BEGIN.... END CERTIFICATE----- IMPORTANT! It was working when I got proper (5) amount of dashes and put tags and data on separate lines
4. use keytool. C:\\Java\\JDK\\bcprov.jar was downloaded separately
 C:\\Users\\Ivan>keytool -import -v -trustcacerts -alias key_alias -file C:\\cert.cer -keystore C:\\mystore.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath C:\\Java\\JDK\\bcprov.jar -storepass 123456

*/

public class MyApplication extends Application
{
    private static final String LOG_TAG = \"MyApplication\";
    private androidhttpclient androidhttpclient;

    @Override
    public void onCreate()
    {
        super.onCreate();
        androidhttpclient = createandroidhttpclient();
    }

    @Override
    public void onLowMemory()
    {
        super.onLowMemory();
        shutdownandroidhttpclient();
    }

    @Override
    public void onTerminate()
    {
        super.onTerminate();
        shutdownandroidhttpclient();
    }


    private androidhttpclient createandroidhttpclient()
    {
        Log.d(LOG_TAG,\"createandroidhttpclient\");

        androidhttpclient client = androidhttpclient.newInstance(\"Android\");

        //This is optional call to inject custom BKS that was created from self-signed certificate
        client = addCustomCertificate(client);

        return client;
    }

    public androidhttpclient getandroidhttpclient()
    {
        return androidhttpclient;
    }

    private void shutdownandroidhttpclient()
    {
        if(androidhttpclient!=null && androidhttpclient.getConnectionManager()!=null)
        {
            androidhttpclient.getConnectionManager().shutdown();
        }
    }

    private androidhttpclient addCustomCertificate(androidhttpclient client)
    {
        SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();

        try
        {
            InputStream in = getResources().openRawResource(R.raw.home_server);

            KeyStore trustStore = KeyStore.getInstance(\"BKS\");

            trustStore.load(in,\"123456\".tochararray());
            in.close();

            sf = new SSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
        }
        catch (Exception t)
        {
            DBLog.InsertError(this,t);
        }

        //Lets register our custom factory here
        client.getConnectionManager().getSchemeRegistry().register(new Scheme(\"https\",sf,443));

        return client;
    }
}
这是我使用此客户端的方式(我在AsyncTask中将其称为)
private String processpOST(String url,String requestData)
{
    String responseData = null;
    application = (MyApplication)getApplication();
    androidhttpclient client = application.getandroidhttpclient();
    HttpPost request = new HttpPost(url);

    try
    {
        StringEntity entity = new StringEntity(requestData);
        entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,\"application/json\"));
        request.setEntity(entity);
        ResponseHandler<String> handler = new BasicResponseHandler();
        responseData = client.execute(request,handler);
    }
    catch (Throwable e)
    {
        DBLog.InsertError(ctxt,e);
    }

    return responseData;
}
这种组合似乎100%适用于2.2和2.3设备。当我将片段与DefaultHttpClient一起使用时,我遇到了2.3.1超时请求的问题(Nexus S)     

解决方法

您可以使用Apache HttpClient。
    public HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(\"BKS\");
        InputStream in = getResources().openRawResource(R.raw.mykeystore);
        try {
            trustStore.load(in,\"mypassword\".toCharArray());
        } finally {
            in.close();
        }

        SSLSocketFactory sf = new SSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params,HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params,HTTP.UTF_8);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme(\"http\",PlainSocketFactory.getSocketFactory(),80));
        registry.register(new Scheme(\"https\",sf,443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params,registry);
        return new DefaultHttpClient(ccm,params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}
在Web服务器中,IIS可以创建自签名证书并导出为PFX,然后使用openssl工具将其转换为PEM,将其编辑为仅包含证书,然后使用JDK和Bouncy Castle jar的密钥工具创建包含该证书的密钥库。可以将创建的密钥库导入到您的项目中,如上面的代码所示。     ,我使用“全部信任” SSL连接进行了一些测试:具有Android和自签名服务器证书的HTTPS GET(SSL) 希望对您有帮助:D     ,您可以在此处找到一个示例-唯一的“不寻常”是,如果遥控器返回401(?)代码,则不会通过ѭ3get来获取它,但是会引发异常(也许也可以抛出5xx) )。 上面的示例在SSL上运行,因此可以使用https。关于自签名证书,我什么也不能说。我想我记得其他人说他们有问题,但是我不确定。     ,Android集成了Apache http客户端组件。如果查看链接的“文档”部分,则将找到教程和示例。 如果您搜索Apache Http Client而不是Android Http Client,则会发现很多信息。 编辑:哦-我刚意识到Android中有一个
AndroidHttpClient
类。没用过。看看对我有帮助的答案。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?