使用自签名证书在android中创建安全的客户端 - 服务器连接

iro*_*ion 3 security ssl android

我正在开发一个企业Android应用程序,因此有必要在我的测试阶段在客户端(android模拟器/测试手机)和服务器之间创建一个安全的连接,即使服务器的证书是自签名的,而正在购买合法的证书由公司(我现在控制的东西).

我需要信任服务器的自签名证书及其证书授权,当然,它本身不受Android操作系统的信任.我正在遵循谷歌关于在这个场景中几乎逐字创建HTTPS环境的建议.

我目前面临的问题是,我无法.crt从Google的示例中访问此行中的文件:

InputStream caInput = new BufferedInputStream(
    new FileInputStream("load-der.crt"));
Run Code Online (Sandbox Code Playgroud)

代替上述,我使用:

InputStream caInput = new BufferedInputStream(
getResources().openRawResource(R.raw.mycrtfile));
Run Code Online (Sandbox Code Playgroud)

打开文件所在的InputStream派生自.但是,我得到了一条线. mycrtfile.crt.crt/res/raw/mycrtfile.crtNullPointerException

有没有更好的方式来存储和访问,我需要加载作为的证书文件InputStreamFileInputStream不是存储在内部的原始资源res目录?

Moy*_*Moy 7

有不同的方法来解决您的问题,但这是我使用的方法:所有步骤都在这个链接http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/ 但有些部分可能会混淆所以我会解释所有的过程:

1.将mycrtfile.crt存储在知道路径中我将说c:BKS/mycrtfile.crt.

2. - 要创建您的BKS或密钥库,您将需要文件bcprov-jdk15on-146.jar,这个类将为我们完成所有工作,有不同的版本,但这个适用于我http://www.bouncycastle .org/download/bcprov-jdk15on-146.jar还将此文件存储到C:BKS /

3.-现在你将使用Keytool(keytool附带Java SDK.你应该在包含javac的目录中找到它)来生成我们的密钥库并确保它正常工作去你的cmd并输入"Keytool",你将看到可用的命令,或者您可以访问"C:\ Program Files(x86)\ Java\jre7\bin> keytool".

4.-现在一切就绪,我们可以使用以下命令行生成密钥库:

keytool -importcert -v -trustcacerts -file"c:\ BKS/mycrtfile.crt"-alias certificate -keystore"c:\ BKS/keystore.bks"-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath"c:\BKS/prov-jdk15on-146.jar"-storetype BKS -storepass mysecret

让我们看看这一行是什么(我在这一部分真的很困惑): - "c:\ BKS/mycrtfile.crt":这是你的证书的路径. - "c:\ BKS/keystore.bks"这是我们存储密钥库的路径,您可以更改我使用密钥库的输出名称,只需确保扩展文件是.bks - "c:\ BKS /prov-jdk15on-146.jar":这是我们文件的路径,可以完成所有工作.-mysecret:这是使用密钥库的密码,你需要这个密码,所以不要忘记这一点.

编辑:
4.1-还使用此命令行来验证证书是否已正确导入密钥库:

keytool -list -keystore"res/raw/Keystore.bks"-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath"c:\ BKS/prov-jdk15on-146.jar"-storetype BKS -storepass mysecret

4.2-在此之后你应该看到这样的输出:

RootCA,22.10.2010,trustedCertEntry,Thumbprint(MD5):24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93 IntermediateCA,22.10.2010, trustedCertEntry,Thumbprint(MD5):98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43
这意味着它被正确导入.

5.-在此之后,如果你去你的BKS文件夹,你会看到一个Keystore.bks文件,这意味着我们正在路上.

6.-现在让我们转到ANDROID部分.在你的项目中检查你是否有"raw"文件夹,如果没有在res下创建这个文件夹,它必须在你的项目/ res/raw中.

7.将Keystore.bks文件复制到raw文件夹中.现在一切都准备就绪了.

8 .---现在我们将创建一个类来阅读和信任我们的Keystore:

import java.io.InputStream;
import java.security.KeyStore;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import com.futureconcepts.anonymous.R;
import android.content.Context;


public class Client extends  DefaultHttpClient   {
final Context context;
  public Client(Context context) {
      this.context = context;
  }

  @Override
  protected ClientConnectionManager createClientConnectionManager() {
      SchemeRegistry registry = new SchemeRegistry();
      registry.register(new Scheme("http", 
      PlainSocketFactory.getSocketFactory(), 80));
      // Register for port 443 our SSLSocketFactory with our keystore
      // to the ConnectionManager
      registry.register(new Scheme("https", newSslSocketFactory(),443));

    HttpParams httpParams = new BasicHttpParams();
     HttpConnectionParams.setConnectionTimeout(httpParams,9000);
     HttpConnectionParams.setSoTimeout(httpParams, 9000);

      return new SingleClientConnManager(httpParams, registry);
  }


  private SSLSocketFactory newSslSocketFactory() {
      try {

          // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");//put BKS literal  
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in =context.getResources().openRawResource(R.raw.keystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
          // Pass the keystore to the SSLSocketFactory. The factory is responsible
          // for the verification of the server certificate.
          SSLSocketFactory sf = new SSLSocketFactory(trusted);
          // Hostname verification from certificate

           sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
          return sf;
      } catch (Exception e) {
          throw new AssertionError(e);
      }
  }

}
Run Code Online (Sandbox Code Playgroud)

9.我们现在做了一个请求就是这样做:HttpClient client = new Client(this); ///设置您的Httpclient.

就是现在你只相信你的证书了.我希望这个解释可以帮助您或任何有同样问题的人.