使用自签名证书来创建的Andr​​oid安全客户端 - 服务器连接

人气:1,261 发布:2022-09-10 标签: security ssl android

问题描述

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

I am developing an enterprise android application, thus it is necessary to create a secure connection between the client (android emulator / test phone) and server during my testing phase, even though the server's certificate is self-signed while a legitimate certificate is being bought by the company (something outside my control for now).

我需要信任服务器的自签名证书,其证书颁发机构,这是不是由Android操作系统信任的,当然本身。我下面谷歌的建议,在这种情况下建立HTTPS环境几乎一字不差。

I need to trust the server's self-signed certificate and its certificate-authority, which is not trusted by the android OS natively, of course. I am following google's suggestion for creating an HTTPS environment in this scenario almost verbatim.

我目前所面临的问题是,我无法访问我的 .CRT 文件作为该行从谷歌的例子:

The problem I'm currently facing is that I can't access my .crt file as in this line from google's example:

InputStream caInput = new BufferedInputStream(
    new FileInputStream("load-der.crt"));

在发生上述情况,我使用的:

In place of the above, I am using:

InputStream caInput = new BufferedInputStream(
getResources().openRawResource(R.raw.mycrtfile));

打开的InputStream mycrtfile.crt 导出,其中 .CRT 文件中的 /res/raw/mycrtfile.crt 。不过,我得到一个 NullPointerException异常上线。

to open the InputStream derived from mycrtfile.crt, where the .crt file exists in /res/raw/mycrtfile.crt. However, I get a NullPointerException on that line.

有没有更好的方式来存储和访问,我需要加载作为的InputStream 的FileInputStream 不是存储在 RES 目录内的原始资源?

Is there a better way to store and access the cert file which I need to load as an InputStream or FileInputStream than as a raw resource stored inside the res directory?

推荐答案

有不同的方法来解决你的问题,但这里是我使用: 所有的步骤都是在这个环节 HTTP://blog.antoine 。李/ 2010/10/22 / Android的信任-SSL-证书/ 但有些部分可以被混淆,所以我会解释所有的过程:

There is different ways to solve your problem but here is the one I use: All the steps are in this link http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/ but some parts can be confused so I will explain all the process:

1,存放在专门路径,我会说你mycrtfile.crt C:BKS / mycrtfile.crt

1.-Store your mycrtfile.crt in a know path I will say c:BKS/mycrtfile.crt.

2,要创建BKS或密钥存储区,您将需要的文件bcprov-jdk15on-146.jar,这个类将尽一切为我们的工作,也有不同的版本,但这个对我的作品的 http://www.bouncycastle.org/download/bcprov-jdk15on-146.jar 同时这个文件保存到C:BKS /

2.-To create your BKS or key store you will need the file bcprov-jdk15on-146.jar, this class will do all the work for us, there are different versions but this one works for me http://www.bouncycastle.org/download/bcprov-jdk15on-146.jar also store this file into C:BKS/

3,现在,您将使用Keytool(密钥工具自带的Java SDK,你会发现它包含javac的目录)来产生我们的密钥库,并确保正在转到您的CMD,输入的Keytool ,你会看到可用的命令,这意味着正在工作,或者你可以访问低谷C:\ Program Files文件(x86)的\的Java \ jre7 \ BIN>密钥工具

3.-Now you will use the Keytool (keytool comes with the Java SDK. You should find it in the directory that contains javac) to generate our keystore and to make sure that is working go to your cmd and type "Keytool", you will see the available commands which means is working, or you can access trough "C:\Program Files (x86)\Java\jre7\bin>keytool".

4,现在万事俱备,我们可以生成使用此命令行密钥库:

4.-Now that everything is in place we can generate the keystore with this command line:

密钥工具-importcert -v -trustcacerts - 文件C:\ BKS / mycrtfile.crt-alias证书-keystoreC:\ BKS / keystore.bks-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath C:\ BKS /省,jdk15on-146.jar-storetype BKS -storepass mysecret

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 /省,jdk15on-146.jar:这是通向我们的文件,将完成所有的工作。 -mysecret:这是使用你需要这个密码的密钥存储,所以不要忘了这个密码

Lets see what is in this line (I was really confused in this part): -"c:\BKS/mycrtfile.crt" : this is the path to your certificate. -"c:\BKS/keystore.bks" this is the path where we will store the keystore and you can change the out-put name I use keystore, just make sure that the extension file is .bks -"c:\BKS/prov-jdk15on-146.jar": this is the path to our file that will do all the job. -mysecret: this is the password to use the key store you will need this password so don't forget about this.

编辑: 4.1-还可以使用此命令行来验证,如果证书被正确导入密钥库:

EDITED: 4.1- Also use this command line to Verify if the certificate were imported correctly into the keystore:

密钥工具-list -keystoreRES /生/ Keystore.bks-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpathC:\ BKS /省,jdk15on-146.jar-storetype BKS -storepass mysecret

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-之后,你应该会看到像这样的输出:

4.2- After this you should see a output like this:

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

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 Which means it was imported correctly.

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

5.- After this if you go to your BKS folder you will se a Keystore.bks file which means we are on the way.

6 .-现在让我们进入了Android的部分。在你的项目检查,如果你有原始文件夹,它是在Yourproject / RES /原料如果不是在创建资源此文件夹。

6.- Now lets go to the ANDROID part. IN your project check if you have the "raw" folder it has to be in Yourproject/res/raw if not create this folder under res.

7-复制你的Keystore.bks文件到原始文件夹。一切都在地方现在让我们去到code。

7.-copy your Keystore.bks file in to the raw folder. Everything is on place now lets go to the code.

8 .---现在,我们将创建一个类来读取和信任我们的密钥库:

8.--- Now we will create a class to read and trust our 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);
      }
  }

}

【译文】而且我们现在做是为了请求只是这样做:     HttpClient的客户端=新的客户端(本);     /// setupo您的HttpClient。

9.And we done now to make a request just do this: HttpClient client= new Client(this); ///setupo your Httpclient.

这就是现在你只信任你的证书。我希望这个解释,帮助你或任何一个同样的问题。

That's it now you will only trust your certificate. I hope this explanation help you or any one with the same problem.

941