如何在Android设备上安装可信CA证书?

问题描述 投票:116回答:7

我已经创建了自己的CA证书,现在我想在我的Android Froyo设备(HTC Desire Z)上安装它,以便设备信任我的证书。

Android将CA证书存储在/system/etc/security/cacerts.bks的Java密钥库中。我将文件复制到我的计算机,使用portecle 1.5添加了我的证书并将其推回设备。

现在,Android似乎没有自动重新加载文件。我在几篇博客文章中看到我需要重启设备。这样做会导致文件再次被原始文件覆盖。

我的下一个尝试是通过复制它并使用设置菜单中的相应选项从SD卡安装证书。设备告诉我证书已经安装,但显然它不信任证书。此外,当我尝试将密钥库复制到我的计算机时,我仍然找到原始库存cacerts.bks

那么,在Android 2.2设备上安装我自己的根CA证书作为可信证书的正确方法是什么?有没有办法以编程方式进行?

android ssl installation certificate
7个回答
87
投票

在Android KitKat之前,您必须使用root设备来安装新证书。

从Android KitKat(4.0)到Nougat(7.0),它可以轻松实现。我能够在我的非root设备上安装Charles Web Debbuging Proxy证书,并成功嗅探SSL流量。

http://wiki.cacert.org/FAQ/ImportRootCert中提取

在Android 4.0版之前,使用Android版Gingerbread&Froyo,有一个只读文件(/system/etc/security/cacerts.bks),其中包含信任存储,默认情况下信任所有CA('系统')证书Android系统。系统应用程序和使用Android SDK开发的所有应用程序都使用此功能。使用这些说明在Android Gingerbread,Froyo上安装CAcert证书,...

从Android 4.0(Android ICS /'Ice Cream Sandwich',Android 4.3'Jelly Bean'和Android 4.4'KitKat')开始,系统可信证书位于'/ system / etc /文件夹中的(只读)系统分区上安全性/'作为单个文件。但是,用户现在可以轻松添加自己的“用户”证书,这些证书将存储在“/ data / misc / keychain / certs-added”中。

系统安装的证书可以在Android设备上的“设置” - >“安全性” - >“证书” - >“系统”部分进行管理,而用户可信证书则可以在“用户”部分进行管理。使用用户可信证书时,Android会强制Android设备的用户实施其他安全措施:使用用户提供的证书时,必须使用PIN码,模式锁或密码来解锁设备。

将CAcert证书安装为“用户信任”证书非常简单。将新证书安装为“系统可信”证书需要更多工作(并且需要root访问权限),但它具有避免Android锁定屏幕要求的优势。

从Android N开始,它变得更加轻松,请参阅Charles proxy website的这个摘录:

从Android N开始,您需要为您的应用添加配置,以使其信任Charles SSL Proxying生成的SSL证书。这意味着您只能对您控制的应用程序使用SSL代理。

要将您的应用配置为信任Charles,您需要向应用添加网络安全配置文件。此文件可以覆盖系统默认值,使您的应用程序可以信任用户安装的CA证书(例如Charles Root证书)。您可以指定这仅适用于应用程序的调试版本,以便生产版本使用默认信任配置文件。

将文件res / xml / network_security_config.xml添加到您的应用程序:

<network-security-config>    
    <debug-overrides> 
        <trust-anchors> 
            <!-- Trust user added CAs while debuggable only -->
            <certificates src="user" /> 
        </trust-anchors>    
    </debug-overrides>  
</network-security-config>

然后在应用的清单中添加对此文件的引用,如下所示:

<?xml version="1.0" encoding="utf-8"?> 
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
    </application> 
</manifest>

42
投票

我花了很多时间试图找到答案(我需要Android才能看到StartSSL证书)。结论:Android 2.1和2.2允许您导入证书,但仅用于WiFi和VPN。没有用于更新受信任根证书列表的用户界面,但是有关于添加该功能的讨论。目前还不清楚手动更新和替换cacerts.bks文件是否有可靠的解决方法。

详细信息和链接:http://www.mcbsys.com/techblog/2010/12/android-certificates/。在该帖子中,请参阅Android错误11231的链接 - 您可能希望将该投票和查询添加到该错误中。


15
投票

如果您需要HTTPS连接证书,则可以将.bks文件作为原始资源添加到应用程序并扩展DefaultHttpConnection,以便将证书用于HTTPS连接。

public class MyHttpClient extends DefaultHttpClient {

    private Resources _resources;

    public MyHttpClient(Resources resources) {
        _resources = resources;
    }

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

    private SSLSocketFactory newSslSocketFactory() {
        try {
            KeyStore trusted = KeyStore.getInstance("BKS");
            InputStream in = _resources.openRawResource(R.raw.mystore);
            try {
                trusted.load(in, "pwd".toCharArray());
            } finally {
                in.close();
            }
            return new SSLSocketFactory(trusted);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

8
投票

链接here的指南可能会回答原始问题而无需编写自定义SSL连接器。

找到了有关导入根证书的非常详细的操作指南,这些证书实际上会引导您在不同版本的Android设备(以及其他设备)上安装可信CA证书。

基本上你需要:

  1. 下载:手机中的cacerts.bks文件。 adb pull /system/etc/security/cacerts.bks cacerts.bks
  2. 从您要允许的证书颁发机构下载.crt文件。
  3. 使用BouncyCastle Provider修改计算机上的cacerts.bks文件
  4. 将cacerts.bks文件上传回手机并重新启动。

这里有一个更详细的一步一步更新早期的Android手机:How to update HTTPS security certificate authority keystore on pre-android-4.0 device


4
投票

对此有一个更容易的解决方案,而不是在这里发布,或在相关的线程中。如果您正在使用webview(就像我一样),您可以通过在其中执行JAVASCRIPT函数来实现此目的。如果您没有使用webview,则可能需要为此目的创建一个隐藏的视图。这是一个适用于任何浏览器(或webview)的功能,以启动安装(通常通过共享的os证书库,包括在Droid上)。它使用iFrames的一个很好的技巧。只需将url传递给.crt文件即可:

function installTrustedRootCert( rootCertUrl ){
    id = "rootCertInstaller";
    iframe = document.getElementById( id );
    if( iframe != null ) document.body.removeChild( iframe );
    iframe = document.createElement( "iframe" );
    iframe.id = id;
    iframe.style.display = "none";
    document.body.appendChild( iframe );
    iframe.src = rootCertUrl;
}

更新:

iframe技巧适用于具有API 19及更高版本的Droids,但旧版本的webview不会像这样工作。一般的想法仍然有效 - 只需用webview下载/打开文件,然后让操作系统接管。这可能是一个更简单,更通用的解决方案(现在在实际的java中):

 public static void installTrustedRootCert( final String certAddress ){
     WebView certWebView = new WebView( instance_ );
     certWebView.loadUrl( certAddress );
 }

请注意,instance_是对Activity的引用。如果您知道证书的URL,这将完美地工作。但是,在我的情况下,我使用服务器端软件动态解决这个问题。我不得不添加大量额外的代码来拦截重定向url并以一种不会导致基于线程并发症的崩溃的方式调用它,但我不会在这里添加所有这些混淆...


3
投票

我所做的能够使用starttls证书非常容易。 (在我的根电话上)

我将/system/etc/security/cacerts.bks复制到了我的SD卡

下载http://www.startssl.com/certs/ca.crthttp://www.startssl.com/certs/sub.class1.server.ca.crt

去了portecle.sourceforge.net并直接从网页上运行了portecle。

从我的SD卡打开我的cacerts.bks文件(当被要求输入密码时没有输入)

在portacle中选择import并打开sub.class1.server.ca.crt,我的情况下它已经有了ca.crt,但也许你需要安装它。

保存密钥库并将其复制回/system/etc/security/cacerts.bks(我先备份该文件以防万一)

重新启动我的手机,现在我可以访问我的网站使用startssl证书没有错误。


0
投票

这是一个替代解决方案,实际上将您的证书添加到内置的默认证书列表中:Trusting all certificates using HttpClient over HTTPS

但是,它只适用于您的应用程序。没有办法以编程方式为用户设备上的所有应用程序执行此操作,因为这会带来安全风险。

© www.soinside.com 2019 - 2024. All rights reserved.