我怎么能引脚广场OKHTTP证书? [英] How can I pin a certificate with Square OKHTTP?

查看:173
本文介绍了我怎么能引脚广场OKHTTP证书?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我需要创建一个新的SSL套接字工厂? 另外,我不希望使用全局SSL环境( https://github.com/square/okhttp/issues/ 184 )出于显而易见的原因。

I think I need to create a new SSL Socket Factory? Also, I don't want to use the global SSL Context (https://github.com/square/okhttp/issues/184) for obvious reasons.

谢谢!

编辑:

由于okhttp的2.1.0可以钉住证书很容易。

As of okhttp 2.1.0 you can pin certificates very easily.

请参阅<一href="https://github.com/square/okhttp/blob/83090befcca69b44c257b96afb519ca66282ca63/okhttp/src/main/java/com/squareup/okhttp/CertificatePinner.java#L43">the来源$ C ​​$ C这里上手

推荐答案

读书的这个博客帖子我能够改变观念与OkHttp使用。如果你想避免使用全局SSL上下文,你应​​该至少使用2.0版本。

After reading this blog post I was able to modify the concept for use with OkHttp. You should use at least version 2.0 if you want to avoid using a global SSL context.

此修改仅适用于OkHttp的当前实例,并改变该实例,以便它的接受证书从指定的证书。如果你想其他证书(如来自微博)被接受,你只需要创建一个新的OkHttp实例,无需作出如下修改。

This modification applies only to the current instance of OkHttp, and changes that instance so that it only accepts certificates from the certificate specified. If you want other certificates (such as one from Twitter) to be accepted, you simply need to create a new OkHttp instance without the modifications described below.

为了引脚的证书,你首先需要创建一个包含该证书信任库。要创建我们将使用nelenkov这个方便的脚本稍加修改我们的目的的信任库:

In order to pin a certificate, you first need to create a truststore containing this certificate. To create the truststore we will use this handy script from nelenkov slightly modified for our purposes:

#!/bin/bash

if [ "$#" -ne 3 ]; then
  echo "Usage: importcert.sh <CA cert PEM file> <bouncy castle jar> <keystore pass>"
  exit 1
fi

CACERT=$1
BCJAR=$2
SECRET=$3

TRUSTSTORE=mytruststore.bks
ALIAS=`openssl x509 -inform PEM -subject_hash -noout -in $CACERT`

if [ -f $TRUSTSTORE ]; then
    rm $TRUSTSTORE || exit 1
fi

echo "Adding certificate to $TRUSTSTORE..."
keytool -import -v -trustcacerts -alias $ALIAS \
      -file $CACERT \
      -keystore $TRUSTSTORE -storetype BKS \
      -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \
      -providerpath $BCJAR \
      -storepass $SECRET

echo "" 
echo "Added '$CACERT' with alias '$ALIAS' to $TRUSTSTORE..."

要运行该脚本,你需要三样东西:

To run this script you need 3 things:

  1. 确保密钥工具(包含在Android SDK中)就在你的$ PATH。
  2. 确保您有最新的BouncyCastle的jar文件下载在同一目录的脚本。 (这里下载
  3. 您想销证书。
  1. Make sure keytool (included in Android SDK) is on your $PATH.
  2. Make sure you have the latest BouncyCastle jar file download in the same dir as the script. (Download here)
  3. The certificate you want to pin.

现在运行脚本

./gentruststore.sh your_cert.pem bcprov-jdk15on-150.jar your_secret_pass

键入是信任证书,并完成在 mytruststore.bks 将在当前目录生成的。

Type 'yes' to trust the certificate, and when complete mytruststore.bks will be generated in your current dir.

创建一个目录在你的 RES 文件夹。复制 mytruststore.bks 在这里。

Create a directory raw under your res folder. Copy mytruststore.bks here.

现在这里有一个销你的证书,以OkHttp非常简单的类

Now here's a very simple class that pins your cert to OkHttp

import android.content.Context;
import android.util.Log;

import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

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

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


/**
 * Created by martin on 02/06/14.
 */
public class Pinning {

    Context context;
    public static String TRUST_STORE_PASSWORD = "your_secret";
    private static final String ENDPOINT = "https://api.yourdomain.com/";

    public Pinning(Context c) {
        this.context = c;
    }

    private SSLSocketFactory getPinnedCertSslSocketFactory(Context context) {
        try {
            KeyStore trusted = KeyStore.getInstance("BKS");
            InputStream in = context.getResources().openRawResource(R.raw.mytruststore);
            trusted.load(in, TRUST_STORE_PASSWORD.toCharArray());
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                    TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trusted);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            Log.e("MyApp", e.getMessage(), e);
        }
        return null;
    }

    public void makeRequest() {
        try {
            OkHttpClient client = new OkHttpClient();
            client.setSslSocketFactory(getPinnedCertSslSocketFactory(context));

            Request request = new Request.Builder()
                    .url(ENDPOINT)
                    .build();

            Response response = client.newCall(request).execute();

            Log.d("MyApp", response.body().string());

        } catch (Exception e) {
            Log.e("MyApp", e.getMessage(), e);

        }
    }
}

正如你可以看到我们实例 OkHttpClient 的新实例,并调用 setSslSocketFactory ,传递一个 SSLSocketFactory的与我们的自定义信任库。请确保您设置 TRUST_STORE_PASSWORD 为您传递到shell脚本的密码。你OkHttp实例现在应该只接受指定的证书。

As you can see we instantiate a new instance of OkHttpClient and call setSslSocketFactory, passing in a SSLSocketFactory with our custom truststore. Make sure you set TRUST_STORE_PASSWORD to the password you passed into the shell script. Your OkHttp instance should now only accept the certificate you specified.

这篇关于我怎么能引脚广场OKHTTP证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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