如何在Android设备上安装受信任的CA证书?


134

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

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

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

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

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


您可以在此处假设手机已植根。:)
比约恩Marschollek

Answers:


115

在使用Android KitKat之前,您必须先植根设备才能安装新证书。

从Android KitKat(4.0)到Nougat(7.0),这都是可能且容易的。我能够在无根设备上安装Charles Web Debbuging Proxy证书,并成功嗅探SSL流量。

摘录自http://wiki.cacert.org/FAQ/ImportRootCert

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

从Android 4.0(Android ICS /“冰淇淋三明治”,Android 4.3“果冻豆”和Android 4.4“ KitKat”)开始,系统受信任证书位于文件夹“ / system / etc /”中的(只读)系统分区上。 security /'作为单个文件。但是,用户现在可以轻松添加自己的“用户”证书,这些证书将存储在“ / data / misc / keychain / certs-added”中。

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

将CAcert证书安装为“用户信任”证书非常容易。将新证书安装为“系统受信任”证书需要进行更多工作(并且需要root访问权限),但是它具有避免Android锁屏要求的优点。

从Android N开始,它变得更加困难,请参阅Charles代理网站中的以下摘录:

从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>

1
/system/etc/security/cacerts/*.0重新启动/重新启动AVD后,我的自定义证书文件()未保留,因此该解决方案未成功。
fikr4n

@BornToCode有趣-我很少使用AVD,所以我不知道这个限制
Dean Wild

我看到了设置debug-overrides,这是否意味着该network_security_config目标定位调试变量?如果我有其他变体,例如UAT变体,那么这行不通吗?
以撒

1
@Isaac,这意味着它将适用于debuggable = true的所有变体
Dean Wild,

1
@DeanWild-非常感谢!我尝试使它永久运行,并在调试我的应用程序时不断获得“无效的ssl证书”。该解决方案工作就像一个魅力对我的Android应用程序运行在Android 9日三星注8
戴维黑

43

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

详细信息和链接:http : //www.mcbsys.com/techblog/2010/12/android-certificates/。在该帖子中,请参阅指向Android错误11231的链接-您可能需要对该错误进行投票并进行查询。


3
一位Android开发人员回答了我的查询。更新cacerts.bks:“在2.3以上的所有版本中,都需要OTA才能在非root用户的电话上更新cacerts.bks。” code.google.com/p/android/issues/detail?id=11231#c25。OTA =空中广播,对不对?这可能就是为什么您的手机不断恢复出厂cacerts.bks的原因吗?但是,如果您确实具有root用户访问权限,则似乎应该可以下载源代码,添加证书,然后使用certimport.sh脚本构建cacerts.bks。android.git.kernel.org/?p=platform/libcore.git;a=tree;f=luni/…
马克·贝里

谢谢。这显然不是我想听到的答案,但似乎是正确的答案。我希望有一种无需更新整个系统即可安装证书的方法。我当然可以用root用户访问权限来构建新的cacerts.bks,甚至可以替换旧的cacerts.bks,但是每次重新启动后它都会恢复为原始版本。如果不重新启动,Android似乎拒绝重新加载受信任的证书文件。
比约恩Marschollek

27
在3.X和4.X平台上安装CA证书怎么办?
Alok Kulkarni


16

如果您需要用于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);
        }
    }
}

感谢您的回复。实际上,我需要以一种使设备上的每个应用程序都信任证书的方式来安装证书。对于某些较小的CA(例如CAcert),也应该存在相同的问题,默认情况下其证书不受信任。他们如何安装证书?
比约恩Marschollek

您是否尝试过:设置->安全->从SD卡安装
Alexander Egger 2010年


2
我有同样的问题,我必须使用Adroid 2.3.3应用程序加载.PDX X509证书,然后创建SSL连接。谁能帮我提供注释代码?
AndroidLearner

9

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

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

基本上,您需要:

  1. 下载:手机中的cacerts.bks文件。

    亚行拉/system/etc/security/cacerts.bks cacerts.bks

  2. 从您要允许的证书颁发机构下载.crt文件。

  3. 使用BouncyCastle Provider修改计算机上的cacerts.bks文件

  4. 将cacerts.bks文件上传回手机并重新启动。

这是逐步更新早期android手机的更详细的步骤: 如何在android-4.0之前的设备上更新HTTPS安全证书颁发机构密钥库


5

比这里或相关主题中提供的解决方案更简单。如果您使用的是Webview(就我而言),则可以通过在其中执行JAVASCRIPT函数来实现。如果您不使用Web视图,则可能需要为此创建一个隐藏的视图。这是一个可以在几乎所有浏览器(或Web视图)中启动ca安装的功能(通常是通过共享的os cert存储库,包括在Droid上)。它对iFrame使用了一个很好的技巧。只需将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,并以不会导致基于线程复杂性的崩溃的方式调用此方法,但在这里我不会添加所有这些困惑。


3

为了能够使用startssl证书,我所做的事情非常简单。(在我的手机上)

我将/system/etc/security/cacerts.bks复制到了sdcard

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

进入portecle.sourceforge.net并直接从网页运行portecle。

从我的sdcard中打开了我的cacerts.bks文件(要求输入密码时未输入任何内容)

在portacle中选择import并打开sub.class1.server.ca.crt,就我而言,它已经有了ca.crt了,但是也许您也需要安装它。

保存密钥库并将其baxck复制到/system/etc/security/cacerts.bks(为防万一,我首先对该文件进行了备份)

重新启动了手机,现在我可以使用startssl证书访问我的网站,而不会出现错误。


Mozilla的新增功能:不信任新的WoSign和StartCom证书
jww

任何想法如何将cacert.bks放回非根设备上?
鲍勃·鲍勃,

1

这些步骤对我有用:

  1. 在您的移动设备上安装Android Dory证书应用程序:https : //play.google.com/store/apps/details? id=io.tempage.dorycert &hl=zh_CN
  2. 使用USB电缆将移动设备连接到笔记本电脑。
  3. 在内部电话内存上创建根文件夹,将证书文件复制到该文件夹​​中并断开电缆连接。
  4. 打开Android Dory证书应用程序,单击圆形的[+]按钮,然后选择正确的“导入文件证书”选项。
  5. 选择格式,提供一个名称(我键入的名称与文件名相同),浏览证书文件,然后单击[确定]。
  6. 将列出三张卡片。我忽略了只有[SIGN CSR]按钮的卡,然后单击了另外两张卡上的[INSTALL]按钮。
  7. 我刷新了PWA Web应用程序,但没有打开我的移动Chrome(它托管在本地IIS Web服务器上),而且呼呼!没有Chrome警告消息。绿锁在那里。它正在工作。

另外,我发现这些选项我不需要尝试,但看起来很容易遵循:

最后,它可能无关紧要,但是,如果您要为托管在本地IIS Web服务器上的PWA应用程序(网站)创建并设置自签名证书(使用mkcert),请遵循以下页面:

https://medium.com/@aweber01/locally-trusted-development-certificates-with-mkcert-and-iis-e09410d92031

谢谢,希望对你有帮助!!:)


0

这是实际上将您的证书添加到默认证书的内置列表中的另一种解决方案:使用HttpClient over HTTPS信任所有证书

但是,它仅适用于您的应用程序。无法对用户设备上的所有应用程序进行编程编程,因为这将带来安全风险。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.