Android上的SSL(通过BouncyCastle)

sve*_*ija 1 ssl android bouncycastle

http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

我按照这个教程,一切似乎都很好(我没有在路上得到任何错误),但我又得到了

06-24 18:42:31.746: WARN/System.err(14807): javax.net.ssl.SSLException: Not trusted server certificate
06-24 18:42:31.756: WARN/System.err(14807): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
06-24 18:42:31.766: WARN/System.err(14807): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
Run Code Online (Sandbox Code Playgroud)

我在http://subdomain.domain.com上有SSL - RapidSSL.我下载了(单个)证书并将其插入密钥库.添加了myHttpClient但又一次,我无法使https工作.

有什么建议?

编辑:在桌面上一切都很好 - 我没有得到任何错误/警告.

Jar*_*iuk 5

例如,尝试http://www.digicert.com/help/ - 粘贴到您网站的URL中,您将看到证书是否已正确安装.通常,为了正确安装证书,您不仅需要安装证书,还需要安装证书颁发机构的中间证书.他们通常不会使用他们的主要证书签署您的证书,而是使用一些中间证书,如果出现任何问题他们可能会失效,并且不像主要证书那样"宝贵" - 这意味着您的证书在链中排名第三:

主权证书 - >中间权威证书 - >您自己的证书

因此,您不仅要告诉您的客户您的证书,还要告诉您的证书.安装说明通常可在您的认证机构帐户中找到.


Vip*_*pul 5

为实现这一目标,我遵循详细的逐步说明

  • http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar下载bouncycastle JAR, 或从"doc"文件夹中下载.
  • 使用以下方法之一配置BouncyCastle for PC.
    • 静态添加BC提供程序(推荐)
      • 将bcprov-ext-jdk15on-1.46.jar复制到每个
        • D:\ tools\jdk1.5.0_09\jre\lib\ext(JDK(捆绑的JRE)
        • D:\ tools\jre1.5.0_09\lib\ext(JRE)
        • C:\(在env变量中使用的位置)
      • 修改下的java.security文件
        • d:\工具\ jdk1.5.0_09\JRE\lib\security中
        • d:\工具\ jre1.5.0_09\lib\security中
        • 并添加以下条目
          • security.provider.7 = org.bouncycastle.jce.provider.BouncyCastleProvider
      • 在"用户变量"部分中添加以下环境变量
        • CLASSPATH =%CLASSPATH%; C:\ bcprov-EXT-jdk15on-1.46.jar
    • 将bcprov-ext-jdk15on-1.46.jar添加到项目的CLASSPATH中,并在代码中添加以下行
      • Security.addProvider(new BouncyCastleProvider());
  • 使用Bouncy Castle生成Keystore
    • 运行以下命令
      • keytool -genkey -alias myproject -keystore C:/myproject.keystore -storepass myproject -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
    • 这将生成文件C:\ myproject.keystore
    • 运行以下命令以检查是否正确生成
      • keytool -list -keystore C:\ myproject.keystore -storetype BKS
  • 为TOMCAT配置BouncyCastle

    • 打开D:\ tools\apache-tomcat-6.0.35\conf\server.xml并添加以下条目

      • <Connector port ="8443"keystorePass ="myproject"alias ="myproject"keystore ="c:/myproject.keystore"keystoreType ="BKS"SSLEnabled ="true"clientAuth ="false"protocol ="HTTP/1.1"scheme ="https"secure ="true"sslProtocol ="TLS"sslImplementationName ="org.bouncycastle.jce.provider.BouncyCastleProvider"/>
    • 在这些更改后重新启动服务器.

  • 为Android客户端配置BouncyCastle
    • 无需配置,因为Android在提供的"android.jar"内部支持Bouncy Castle版本1.46.
    • 只需实现您的HTTP客户端版本(MyHttpClient.java可以在下面找到)并在代码中设置以下内容
      • SSLSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    • 如果你不这样做,它会给出一个例外,如下所示
      • javax.net.ssl.SSLException:证书中的主机名不匹配:<192.168.104.66>!=
    • 在生产模式下,将上面的代码更改为
      • SSLSocketFactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

MyHttpClient.java

package com.arisglobal.aglite.network;

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 com.arisglobal.aglite.activity.R;

import android.content.Context;

public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(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));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");

            // Get the raw resource, which contains the keystore with your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.aglite);
            try {
                // Initialize the keystore with the provided trusted certificates.
                // Also provide the password of the keystore
                trusted.load(in, "aglite".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
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在Activity类中调用上面的代码:

DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpResponse response = client.execute(...);
Run Code Online (Sandbox Code Playgroud)