如何使用Android的P12证书(客户端证书) [英] How to use p12 certificates in Android (client certificates)

查看:625
本文介绍了如何使用Android的P12证书(客户端证书)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用客户证书机器人。 我说我想用对服务器进行身份验证.p12文件。

我使用portecle到.p12文件转换为.bks文件,但我似乎并没有得到它的工作。

这里的code:

 包com.pa1406.SECURE;

进口的java.io.InputStream;
进口java.security.KeyStore中;

进口javax.net.ssl​​.KeyManagerFactory;
进口javax.net.ssl​​.TrustManagerFactory;

进口org.apache.http.conn.ClientConnectionManager;
进口org.apache.http.conn.scheme.PlainSocketFactory;
进口org.apache.http.conn.scheme.Scheme;
进口org.apache.http.conn.scheme.SchemeRegistry;
进口org.apache.http.conn.ssl.SSLSocketFactory;
进口org.apache.http.impl.client.DefaultHttpClient;
进口org.apache.http.impl.conn.SingleClientConnManager;

进口android.content.Context;

公共类HttpsClient扩展DefaultHttpClient {

  最后上下文的背景下;

  公共HttpsClient(上下文的背景下){
    this.context =背景;
  }

  @覆盖保护ClientConnectionManager createClientConnectionManager(){
    SchemeRegistry注册表=新SchemeRegistry();
    registry.register(
        新的计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
    registry.register(
        新的计划(https开头,newSslSocketFactory(),443));
    返回新SingleClientConnManager(getParams()方法,登记);
  }

  私人的SSLSocketFactory newSslSocketFactory(){
    尝试 {
      密钥库信任库= KeyStore.getInstance(BKS);

      InputStream的时间= context.getResources()openRawResource(R.raw.keystore)。

      尝试 {
          truststore.load(在qwerty1234.toCharArray());
      } 最后 {
        附寄();
      }
      返回新的SSLSocketFactory(信任库);
    }赶上(例外五){
      抛出新的AssertionError(E);
    }

  }
}
 

我能做些什么来做到这一点?

更新:

 包com.pa1406.SECURE;


进口的java.io.InputStream;
进口java.security.KeyStore中;

进口javax.net.ssl​​.KeyManagerFactory;
进口javax.net.ssl​​.SSLContext;
进口javax.net.ssl​​.TrustManagerFactory;

进口org.apache.http.conn.ClientConnectionManager;
进口org.apache.http.conn.scheme.PlainSocketFactory;
进口org.apache.http.conn.scheme.Scheme;
进口org.apache.http.conn.scheme.SchemeRegistry;
进口org.apache.http.conn.ssl.SSLSocketFactory;
进口org.apache.http.impl.client.DefaultHttpClient;
进口org.apache.http.impl.conn.SingleClientConnManager;

进口android.content.Context;

公共类HttpsClient扩展DefaultHttpClient {

  最后上下文的背景下;

  公共HttpsClient(上下文的背景下){
    this.context =背景;
  }

  @覆盖保护ClientConnectionManager createClientConnectionManager(){
    SchemeRegistry注册表=新SchemeRegistry();
    registry.register(
        新的计划(HTTP,PlainSocketFactory.getSocketFactory(),80));
    registry.register(
        新的计划(https开头,newSslSocketFactory(),443));
    返回新SingleClientConnManager(getParams()方法,登记);
  }

  私人的SSLSocketFactory newSslSocketFactory(){
    尝试 {
        //设置信任库提供信任的服务器证书

        //负荷信任库证书
        InputStream的clientTruststoreIs = context.getResources()openRawResource(R.raw.truststore)。
        密钥库的trustStore = NULL;
        的trustStore = KeyStore.getInstance(BKS);
        trustStore.load(clientTruststoreIs​​qwerty1234.toCharArray());

        的System.out.println(加载服务器证书:+ trustStore.size());

        //初始化信任管理器工厂读信任库
        的TrustManagerFactory的TrustManagerFactory = NULL;
        的TrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(的trustStore);

        //设置客户端证书

        //加载客户证书
        InputStream的keyStoreStream = context.getResources()openRawResource(R.raw.torbix)。
        密钥库的keyStore = NULL;
        的keyStore = KeyStore.getInstance(BKS);
        keyStore.load(keyStoreStreamqwerty1234.toCharArray());

        的System.out.println(加载客户证书:+ keyStore.size());

        //与读取客户端证书初始化密钥管理器工厂
        的KeyManagerFactory的KeyManagerFactory = NULL;
        的KeyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(密钥库qwerty1234.toCharArray());

     //初始化SSLSocketFactory的使用证书
        SSLSocketFactory的的SocketFactory = NULL;
        的SocketFactory =新的SSLSocketFactory(SSLSocketFactory.TLS,密钥库qwerty1234
            信任库NULL,NULL);

      返回的SocketFactory;
    }赶上(例外五){
      抛出新的AssertionError(E);
    }

  }

}
 

解决方案

,你必须改变你的code是当该点新的SSLSocketFactory的实例:

 返回新的SSLSocketFactory(信任库);
 

本类SSLSocketFactory有其他的构造函数,其中一个允许指定一个密钥库,密钥库密码和truststure:

公开的SSLSocketFactory(密钥库密钥库,字符串keystorePassword,密钥库信任库)(<一href="http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html#SSLSocketFactory%28java.security.KeyStore,%20java.lang.String,%20java.security.KeyStore%29"相对=nofollow>的JavaDoc )

我不知道,如果你可以加载你的 .P12 Android的下文件的密钥库(在J2SE可以)。如果你不能,你必须在 .P12 文件转换为类似于您正在使用的信任库充气城堡密钥存储。使用该密钥存储区来创建SSLSocketFactory的实例,你应该能够使用客户端证书。

通过Portecle导入P12文件到BKS

创建 BKS 文件并导入现有 .KEY + 质子交换膜文件是非常简单的使用 Portecle GUI (Java程序)。开始Portecle选择的文件后 - >新的密钥库 - > BKS 的。之后,您可以执行的工具 - >导入密钥对的,选择 .P12 文件。 最后,保存您选择的密码保护的密钥存储区。

I'm trying to use client certificates in android. I got a .p12 file that i want to use to authenticate towards the server.

I am using portecle to convert the .p12 file to a .bks file but i don't seem to get it to work.

Here's the code:

package com.pa1406.SECURE;

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

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;

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 android.content.Context;

public class HttpsClient extends DefaultHttpClient {

  final Context context;

  public HttpsClient(Context context) {
    this.context = context;
  }

  @Override protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(
        new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(
        new Scheme("https",newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
  }

  private SSLSocketFactory newSslSocketFactory() {
    try {
      KeyStore truststore = KeyStore.getInstance("BKS");

      InputStream in = context.getResources().openRawResource(R.raw.keystore);

      try {
          truststore.load(in, "qwerty1234".toCharArray());
      } finally {
        in.close();
      }
      return new SSLSocketFactory(truststore);
    } catch (Exception e) {
      throw new AssertionError(e);
    }

  }
}

What can i do to accomplish this?

UPDATE:

package com.pa1406.SECURE;


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

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

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 android.content.Context;

public class HttpsClient extends DefaultHttpClient {

  final Context context;

  public HttpsClient(Context context) {
    this.context = context;
  }

  @Override protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(
        new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(
        new Scheme("https",newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
  }

  private SSLSocketFactory newSslSocketFactory() {
    try {
        // setup truststore to provide trust for the server certificate

        // load truststore certificate
        InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.truststore);
        KeyStore trustStore = null;
        trustStore = KeyStore.getInstance("BKS");
        trustStore.load(clientTruststoreIs, "qwerty1234".toCharArray());

        System.out.println("Loaded server certificates: " + trustStore.size());

        // initialize trust manager factory with the read truststore
        TrustManagerFactory trustManagerFactory = null;
        trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);

        // setup client certificate

        // load client certificate
        InputStream keyStoreStream = context.getResources().openRawResource(R.raw.torbix);
        KeyStore keyStore = null;
        keyStore = KeyStore.getInstance("BKS");
        keyStore.load(keyStoreStream, "qwerty1234".toCharArray());

        System.out.println("Loaded client certificates: " + keyStore.size());

        // initialize key manager factory with the read client certificate
        KeyManagerFactory keyManagerFactory = null;
        keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, "qwerty1234".toCharArray());

     // initialize SSLSocketFactory to use the certificates
        SSLSocketFactory socketFactory = null;
        socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "qwerty1234",
            trustStore, null, null);

      return socketFactory;
    } catch (Exception e) {
      throw new AssertionError(e);
    }

  }

}

解决方案

The point where you have to change your code is when your new SSLSocketFactory instance:

return new SSLSocketFactory(truststore);

The SSLSocketFactory class has other constructors, one of them allows to specify a keystore, the keystore password and a truststure:

public SSLSocketFactory (KeyStore keystore, String keystorePassword, KeyStore truststore)(JavaDoc)

I am not sure if you can load your .P12 file under Android as KeyStore (on J2SE you can). If you can not you have to convert the .P12 file to a Bouncy castle keystore similar to the truststore you are already using. Use that key store to create your SSLSocketFactory instance and you should be able to use the client certificate.

Importing a P12 file into BKS via Portecle

Creating a BKS file and importing existing .key+.pem file is very simple using Portecle GUI (Java program). After starting Portecle select File -> New Keystore -> BKS. Afterwards you can execute Tools -> Import Key Pair and select the .P12 file. Finally save the key store protected with a password of your choice.

这篇关于如何使用Android的P12证书(客户端证书)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆