Двухсторонний SSL в Android: аутентификация клиента не работает - PullRequest
3 голосов
/ 12 августа 2011

Я установил локально на своем компьютере сервер Apache 2. Сначала я настроил его с помощью одностороннего SSL и попытался подключиться к нему с Android. Чтобы настроить свой собственный односторонний сервер SSL Apache 2, мне пришлось создать сертификат сервера. Я сделал это с помощью следующих команд:

openssl genrsa -out server.key 2048

openssl req -config ./openssl.cnf -new -key server.key -out server.req

openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 365 -outform PEM -out server.cer

Затем я взял файл server.cer и преобразовал его в BKS, используя Java Keytool. Аутентификация с Android работала. Затем я продолжил двухстороннюю настройку SSL моего сервера Apache 2 и пытается общаться с ним из Android. Мне не удалось заставить его работать ... Я использовал следующие команды для создания сертификата клиента:

openssl req -config ./openssl.cnf -newkey rsa: 2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer

openssl genrsa -out client.key 2048

openssl req -config ./openssl.cnf -new -key client.key -out client.req

openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 365 -outform PEM из клиента .cer

openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12

Работает из браузера ПК после импорта файла client.p12. Для Android я конвертировал файл client.p12 в формат BKS (используя инструмент Portecle), но, похоже, он не работает. Возможно преобразование не сделано правильно ?! Я всегда получаю javax.net.ssl.SSLPeerUnverifiedException: нет исключения для сертификата пира. У кого-нибудь есть идеи, в чем может быть проблема? Вот это код Android:

  public class SslTestActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {
        // load truststore certificate
        InputStream clientTruststoreIs = getResources().openRawResource(
                R.raw.server);
        KeyStore trustStore = KeyStore.getInstance("BKS");
        trustStore.load(clientTruststoreIs, "mypassword".toCharArray());

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



        // load client certificate
        InputStream keyStoreStream = getResources().openRawResource(
                R.raw.clientt);
        KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(keyStoreStream, "password".toCharArray());
        System.out
                .println("-------Loaded client certificates: " + keyStore.size());


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

        // Set basic data
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");


        // Register http/s shemas!
        SchemeRegistry schReg = new SchemeRegistry();
        schReg.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        schReg.register(new Scheme("https", socketFactory, 443));
        ClientConnectionManager conMgr = new ThreadSafeClientConnManager(
                params, schReg);
        DefaultHttpClient sClient = new DefaultHttpClient(conMgr, params);
        try {
            String res = executeHttpGet(sClient, "https://10.41.0.102/");
            System.out.println("------- SSL RESULT IS = " + res);
        } catch (Exception e) {
            System.out.println("---- ex " + e.getMessage());
            e.printStackTrace();
        }



    } catch (Exception e) {
        System.out.println("------Exception " + e.getMessage());
        e.printStackTrace();
    }
}

public String executeHttpGet(DefaultHttpClient client, String url) throws Exception {
    BufferedReader in = null;
    try {

        HttpGet request = new HttpGet();
        request.setURI(new URI(url));
        HttpResponse response = client.execute(request);

        in = new BufferedReader(new InputStreamReader(response
                .getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");
        while ((line = in.readLine()) != null) {
            sb.append(line + NL);
        }
        in.close();
        String result = sb.toString();
        return result;
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}}

Спасибо

1 Ответ

2 голосов
/ 12 августа 2011

Ваш код кажется правильным. Вот несколько вещей, которые вы можете попробовать:

  1. Перечислите содержимое хранилища ключей из Android, чтобы убедиться, что правильный сертификат существует и доступен для анализа.

  2. Включите отладку SSL на стороне сервера и проверьте журналы

  3. Проверьте logcat, чтобы увидеть, есть ли какие-либо ошибки / предупреждения.
...