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

kat*_*tit 3 android

关于AndroidHttpClient的信息很少,特别是我找不到任何好的例子.从我读到的 - 我可以使用此客户端,它已预先配置为SSL.我的目标是2.2+,所以它对我很有用.

  1. 关于我如何使用它有什么好的样本吗?专门用于REST服务POST
  2. 有关如何允许自签名证书的样本吗?我不介意只允许任何证书与将特定证书导入本地商店.

谢谢!

我自己的答案(见下面的代码).

  1. 我有自带签名证书的IIS服务器.我不得不采取额外步骤并生成与外部名称匹配的证书,而不是服务器名称.
  2. 我使用的是AndroidHttpClient.据说,这个客户端具有Android的所有"正确"设置,并从版本8开始支持
  3. 我在Application对象中创建AndroidHttpClient并在其中共享.
  4. 我将注入自定义证书的代码分开,以便以后很容易将其删除.我注意到在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我如何使用这个客户端(我在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;
}
Run Code Online (Sandbox Code Playgroud)

这种组合似乎100%适用于2.2和2.3设备.当我使用DefaultHttpClient的代码片段时,我遇到了2.3.1超时请求的问题(Nexus S)

bob*_*bob 5

您可以使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在Web服务器中,IIS可以创建自签名证书并导出为PFX,然后使用openssl工具将其转换为PEM,将其编辑为仅使用证书,然后使用JDK的keytool和Bouncy Castle jar创建包含证书的密钥库.可以将创建的密钥库导入到项目中,如上面的代码所示.