Android 上的 SSL(通过 BouncyCastle)

发布于 2024-11-17 01:55:20 字数 994 浏览 3 评论 0原文

http://blog.antoine.li/index.html 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.

http://subdomain.domain.com 上的 SSL - RapidSSL。我下载了(单个)证书并将其插入密钥库。添加了 myHttpClient 但同样,我无法让 https 工作。

有什么建议吗?

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

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

I followed this tutorial and everything seemed to be fine (I didn't get any error(s) on the road) but again I get

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.

I have SSL on http://subdomain.domain.com - RapidSSL. I downloaded the (single) certificate and inserted it into keystore. Added myHttpClient but again, I can't get https to work.

Any suggestions?

EDIT: On desktop everything is just fine - I don't get any errors/warnings at all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不羁少年 2024-11-24 01:55:20

例如,尝试 http://www.digicert.com/help/ - 粘贴您的 URL站点,您将看到证书是否已正确安装。通常,要正确安装证书,您不仅需要安装证书,还需要安装来自证书颁发机构的中间证书。他们通常不会使用主证书来签署您的证书,而是使用一些中间证书,这些中间证书可以在出现任何问题时失效,并且不像主证书那么“珍贵” - 这意味着您的证书在链中处于第三位:

主要权威机构证书->中级权威证书->你自己的证书

所以你不仅要告诉你的客户你的证书,还要告诉你的中间证书。
安装说明通常可在您的认证机构帐户中找到。

Try http://www.digicert.com/help/ for example - paste in the URL of your site and you will see if the certificate is correctly installed. Usually to get the certificate correctly installed you do not only have to install the certificate but also an intermediate certficate from your certificate authority. They usually sign your certs not with their main certificate but using some intermediate ones that they can invalidate in case of any problems and which is not as "precious" as the main one - which means that your certificate is third in the chain:

main authority certificate -> intermediate authority certificate -> your own certificate

So you have to tell your client not only your certificate, but also the intermediate one.
Installation instructions are usually available at your certifcation authority account.

千里故人稀 2024-11-24 01:55:20

我遵循的详细分步说明来实现此目标

  • 从以下位置下载 bouncycastle JAR
    http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar
    或者从“doc”文件夹中获取它。
  • 使用以下方法之一配置适用于 PC 的 BouncyCastle。
    • 静态添加 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:\(环境变量中使用的位置)
      • 修改下面的java.security文件
        • D:\tools\jdk1.5.0_09\jre\lib\security
        • D:\tools\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 生成密钥库
    • 运行以下命令
      • 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 并添加以下条目

      • <连接器
        端口=“8443”
        keystorePass=“我的项目”
        别名=“我的项目”
        密钥库 =“c:/myproject.keystore”
        密钥库类型=“BKS”
        SSL 启用=“真”
        客户端验证=“假”
        协议=“HTTP/1.1”
        方案=“https”
        安全=“真”
        ssl协议=“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);
        }
    }
}

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

DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpResponse response = client.execute(...);

Detailed Step by Step instructions I followed to achieve this

  • Download bouncycastle JAR from
    http://repo2.maven.org/maven2/org/bouncycastle/bcprov-ext-jdk15on/1.46/bcprov-ext-jdk15on-1.46.jar
    or take it from the "doc" folder.
  • Configure BouncyCastle for PC using one of the below methods.
    • Adding the BC Provider Statically (Recommended)
      • Copy the bcprov-ext-jdk15on-1.46.jar to each
        • D:\tools\jdk1.5.0_09\jre\lib\ext (JDK (bundled JRE)
        • D:\tools\jre1.5.0_09\lib\ext (JRE)
        • C:\ (location to be used in env variable)
      • Modify the java.security file under
        • D:\tools\jdk1.5.0_09\jre\lib\security
        • D:\tools\jre1.5.0_09\lib\security
        • and add the following entry
          • security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider
      • Add the following environment variable in "User Variables" section
        • CLASSPATH=%CLASSPATH%;c:\bcprov-ext-jdk15on-1.46.jar
    • Add bcprov-ext-jdk15on-1.46.jar to CLASSPATH of your project and Add the following line in your code
      • Security.addProvider(new BouncyCastleProvider());
  • Generate the Keystore using Bouncy Castle
    • Run the following command
      • keytool -genkey -alias myproject -keystore C:/myproject.keystore -storepass myproject -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
    • This generates the file C:\myproject.keystore
    • Run the following command to check if it is properly generated or not
      • keytool -list -keystore C:\myproject.keystore -storetype BKS
  • Configure BouncyCastle for TOMCAT

    • Open D:\tools\apache-tomcat-6.0.35\conf\server.xml and add the following entry

      • <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"/>
    • Restart the server after these changes.

  • Configure BouncyCastle for Android Client
    • No need to configure since Android supports Bouncy Castle Version 1.46 internally in the provided "android.jar".
    • Just implement your version of HTTP Client (MyHttpClient.java can be found below) and set the following in code
      • SSLSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    • If you don't do this, it gives an exception as below
      • javax.net.ssl.SSLException: hostname in certificate didn't match: <192.168.104.66> !=
    • In production mode, change the above code to
      • 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);
        }
    }
}

How to invoke the above code in your Activity class:

DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpResponse response = client.execute(...);
装迷糊 2024-11-24 01:55:20

查找并下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
http://www.oracle.com/technetwork/java/javase/downloads /index.html

覆盖 JDK 中的 local_policy.jarUS_export_policy.jar

jdk1.7.0_79\jre\lib\security\

并在您的 JRE 中

jre7\lib\安全\

文件夹。

Find and download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files in
http://www.oracle.com/technetwork/java/javase/downloads/index.html

Overwrite the local_policy.jar and US_export_policy.jar in both your JDK's

jdk1.7.0_79\jre\lib\security\

and in your JRE's

jre7\lib\security\

folder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文