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

发布于 2024-10-07 22:47:34 字数 547 浏览 1 评论 0原文

我已经创建了自己的 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 证书作为可信证书的正确方法是什么?有没有办法以编程方式做到这一点?

I have created my own CA certificate and now I want to install it on my Android Froyo device (HTC Desire Z), so that the device trusts my certificate.

Android stores CA certificates in its Java keystore in /system/etc/security/cacerts.bks. I copied the file to my computer, added my certificate using portecle 1.5 and pushed it back to the device.

Now, Android does not seem to reload the file automatically. I have read in several blog posts that I need to restart the device. Doing so results in the file being overwritten with the original one again.

My next try was to install the certificate from SD card by copying it and using the according option from the settings menu. The device tells me that the certificate has been installed, but apparently it does not trust the certificate. Moreover, when I try to copy the keystore to my computer, I still find the original stock cacerts.bks.

So, what is the right way to install my own root CA certificate on an Android 2.2 device as a trusted certificate? Is there a way to do it programmatically?

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

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

发布评论

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

评论(11

独享拥抱 2024-10-14 22:47:34

在 Android KitKat 之前,您必须 root 设备才能安装新证书。

从 Android KitKat (4.0) 到 Marshmallow (6.0) 这都是可能且简单的。我能够在未 root 的设备上安装 Charles Web 调试代理证书并成功嗅探 SSL 流量。

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

Android 4.0 版本之前,Android 版本 Gingerbread & Froyo 中有一个只读文件 ( /system/etc/security/cacerts.bks ),其中包含 Android 上默认信任的所有 CA(“系统”)证书的信任存储。系统应用程序和所有使用 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/security/' 作为单独的文件。但是,用户现在可以轻松添加自己的“用户”证书,该证书将存储在“/data/misc/keychain/certs-added”中。

系统安装的证书可以在Android设备上的“设置”->“管理”中进行管理。安全->证书-> “系统”部分,而用户信任的证书在“用户”部分进行管理。使用用户信任的证书时,Android 将强制 Android 设备的用户实施额外的安全措施:使用用户提供的证书时,必须使用 PIN 码、图案锁或密码来解锁设备。

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

从 Android N (7.0) 开始,它变得更加困难,请参阅 查尔斯代理网站

从 Android N 开始,您需要向应用添加配置才能
让它信任 Charles SSL 代理生成的 SSL 证书。
这意味着您只能对您自己的应用程序使用 SSL 代理
控制。

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

将文件 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>

Prior to Android KitKat you have to root your device to install new certificates.

From Android KitKat (4.0) up to Marshmallow (6.0) it's possible and easy. I was able to install the Charles Web Debbuging Proxy cert on my un-rooted device and successfully sniff SSL traffic.

Extract from http://wiki.cacert.org/FAQ/ImportRootCert

Before Android version 4.0, with Android version Gingerbread & Froyo, there was a single read-only file ( /system/etc/security/cacerts.bks ) containing the trust store with all the CA ('system') certificates trusted by default on Android. Both system apps and all applications developed with the Android SDK use this. Use these instructions on installing CAcert certificates on Android Gingerbread, Froyo, ...

Starting from Android 4.0 (Android ICS/'Ice Cream Sandwich', Android 4.3 'Jelly Bean' & Android 4.4 'KitKat'), system trusted certificates are on the (read-only) system partition in the folder '/system/etc/security/' as individual files. However, users can now easily add their own 'user' certificates which will be stored in '/data/misc/keychain/certs-added'.

System-installed certificates can be managed on the Android device in the Settings -> Security -> Certificates -> 'System'-section, whereas the user trusted certificates are manged in the 'User'-section there. When using user trusted certificates, Android will force the user of the Android device to implement additional safety measures: the use of a PIN-code, a pattern-lock or a password to unlock the device are mandatory when user-supplied certificates are used.

Installing CAcert certificates as 'user trusted'-certificates is very easy. Installing new certificates as 'system trusted'-certificates requires more work (and requires root access), but it has the advantage of avoiding the Android lockscreen requirement.

From Android N (7.0) onwards it gets a littler harder, see this extract from the Charles proxy website:

As of Android N, you need to add configuration to your app in order to
have it trust the SSL certificates generated by Charles SSL Proxying.
This means that you can only use SSL Proxying with apps that you
control.

In order to configure your app to trust Charles, you need to add a
Network Security Configuration File to your app. This file can
override the system default, enabling your app to trust user installed
CA certificates (e.g. the Charles Root Certificate). You can specify
that this only applies in debug builds of your application, so that
production builds use the default trust profile.

Add a file res/xml/network_security_config.xml to your app:

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

Then add a reference to this file in your app's manifest, as follows:

<?xml version="1.0" encoding="utf-8"?> 
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
    </application> 
</manifest>
川水往事 2024-10-14 22:47:34

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

详细信息和链接:http://www.mcbsys.com/techblog/2010/ 12/android-证书/。在那篇文章中,请参阅 Android bug 11231 的链接——您可能想向该 bug 添加您的投票和查询。

I spent a lot of time trying to find an answer to this (I need Android to see StartSSL certificates). Conclusion: Android 2.1 and 2.2 allow you to import certificates, but only for use with WiFi and VPN. There is no user interface for updating the list of trusted root certificates, but there is discussion about adding that feature. It’s unclear whether there is a reliable workaround for manually updating and replacing the cacerts.bks file.

Details and links: http://www.mcbsys.com/techblog/2010/12/android-certificates/. In that post, see the link to Android bug 11231--you might want to add your vote and query to that bug.

铁憨憨 2024-10-14 22:47:34

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

If you need your certificate for HTTPS connections you can add the .bks file as a raw resource to your application and extend DefaultHttpConnection so your certificates are used for HTTPS connections.

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);
        }
    }
}
陈独秀 2024-10-14 22:47:34

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

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

基本上您需要:

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

    adb pull /system/etc/security/cacerts.bks cacerts.bks

  2. 从您想要允许的认证机构下载 .crt 文件。

  3. 计算机上的 cacerts.bks 文件
  4. 上传 cacerts.bks 文件返回您的手机并重新启动。

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

The guide linked here will probably answer the original question without the need for programming a custom SSL connector.

Found a very detailed how-to guide on importing root certificates that actually steps you through installing trusted CA certificates on different versions of Android devices (among other devices).

Basically you'll need to:

  1. Download: the cacerts.bks file from your phone.

    adb pull /system/etc/security/cacerts.bks cacerts.bks

  2. Download the .crt file from the certifying authority you want to allow.

  3. Modify the cacerts.bks file on your computer using the BouncyCastle Provider

  4. Upload the cacerts.bks file back to your phone and reboot.

Here is a more detailed step by step to update earlier android phones:
How to update HTTPS security certificate authority keystore on pre-android-4.0 device

萌辣 2024-10-14 22:47:34

如果您有 root 设备,则可以使用 Magisk 模块将用户证书移动到系统,以便它将成为受信任的证书

https://github.com/Magisk-Modules-Repo/movecert

If you have a rooted device, you can use a Magisk Module to move User Certs to System so it will be Trusted Certificate

https://github.com/Magisk-Modules-Repo/movecert

ぽ尐不点ル 2024-10-14 22:47:34

有一个比在此处或相关线程中发布的更简单的解决方案。如果您使用的是 webview(就像我一样),您可以通过在其中执行 JAVASCRIPT 函数来实现此目的。如果您不使用网络视图,您可能需要为此目的创建一个隐藏的网络视图。这是一个几乎可以在任何浏览器(或 webview)中运行的函数,用于启动 ca 安装(通常通过共享操作系统证书存储库,包括在 Droid 上)。它使用了 iFrame 的一个很好的技巧。只需将 .crt 文件的 url 传递给此函数:

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 及更高版本的 Droid,但旧版本的 webview 无法像这样工作。不过,总体思路仍然有效 - 只需使用网络视图下载/打开文件,然后让操作系统接管即可。这可能是一个更简单、更通用的解决方案(在现在的实际 java 中):

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

请注意,instance_ 是对 Activity 的引用。如果您知道证书的 url,这将非常有效。然而,就我而言,我使用服务器端软件动态解决该问题。我必须添加大量额外代码来拦截重定向 url,并以不会因线程复杂性而导致崩溃的方式调用它,但我不会在这里添加所有这些混乱...

There is a MUCH easier solution to this than posted here, or in related threads. If you are using a webview (as I am), you can achieve this by executing a JAVASCRIPT function within it. If you are not using a webview, you might want to create a hidden one for this purpose. Here's a function that works in just about any browser (or webview) to kickoff ca installation (generally through the shared os cert repository, including on a Droid). It uses a nice trick with iFrames. Just pass the url to a .crt file to this function:

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;
}

UPDATE:

The iframe trick works on Droids with API 19 and up, but older versions of the webview won't work like this. The general idea still works though - just download/open the file with a webview and then let the os take over. This may be an easier and more universal solution (in the actual java now):

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

Note that instance_ is a reference to the Activity. This works perfectly if you know the url to the cert. In my case, however, I resolve that dynamically with the server side software. I had to add a fair amount of additional code to intercept a redirection url and call this in a manner which did not cause a crash based on a threading complication, but I won't add all that confusion here...

谁把谁当真 2024-10-14 22:47:34

您是否尝试过:设置 ->安全->从 SD 卡安装? – Alexander Egger,2010 年 12 月 20 日 20:11

我不确定为什么这还不是答案,但我只是遵循了这个建议,它起作用了。

Did you try: Settings -> Security -> Install from SD Card? – Alexander Egger Dec 20 '10 at 20:11

I'm not sure why is this not an answer already, but I just followed this advice and it worked.

ゃ人海孤独症 2024-10-14 22:47:34

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

我将/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 中导入并打开 sub.class1.server.ca.crt,在我的情况下,它已经有了 ca.crt 但也许你需要安装那也是。

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

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

What I did to beable to use startssl certificates was quite easy. (on my rooted phone)

I copied /system/etc/security/cacerts.bks to my sdcard

Downloaded http://www.startssl.com/certs/ca.crt and http://www.startssl.com/certs/sub.class1.server.ca.crt

Went to portecle.sourceforge.net and ran portecle directly from the webpage.

Opened my cacerts.bks file from my sdcard (entered nothing when asked for a password)

Choose import in portacle and opened sub.class1.server.ca.crt, im my case it allready had the ca.crt but maybe you need to install that too.

Saved the keystore and copied it baxck to /system/etc/security/cacerts.bks (I made a backup of that file first just in case)

Rebooted my phone and now I can vist my site thats using a startssl certificate without errors.

孤独难免 2024-10-14 22:47:34

这些步骤对我有用:

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

或者,我发现了这些选项,我不需要自己尝试,但看起来很容易遵循:

最后,它可能不相关,但是,如果您希望为本地 IIS Web 服务器上托管的 PWA 应用程序(网站)创建和设置自签名证书(使用 mkcert),我遵循此页面:

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

谢谢,希望有帮助! :)

These steps worked for me:

  1. Install Dory Certificate Android app on your mobile device: https://play.google.com/store/apps/details?id=io.tempage.dorycert&hl=en_US
  2. Connect mobile device to laptop with USB Cable.
  3. Create root folder on Internal Phone memory, copy the certificate file in that folder and disconnect cable.
  4. Open Dory Certificate Android app, click the round [+] button and select the right Import File Certificate option.
  5. Select format, provide a name (I typed same as filename), browse the certificate file and click the [OK].
  6. Three cards will list up. I ignored the card that only had the [SIGN CSR] button and proceeded to click the [INSTALL] button on the two other cards.
  7. I refreshed the PWA web app I had opened no my mobile Chrome (it is hosted on a local IIS Web Server) and voala! No chrome warning message. The green lock was there. It was Working.

Alternatively, I found these options which I had no need to try myself but looked easy to follow:

Finally, it may not be relevant but, if you are looking to create and setup a self-signed certificate (with mkcert) for your PWA app (website) hosted on a local IIS Web server, I followed this page:

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

Thanks and hope it helps!! :)

泪冰清 2024-10-14 22:47:34

这是一个替代解决方案,实际上将您的证书添加到默认证书的内置列表中: 通过 HTTPS 使用 HttpClient 信任所有证书

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

Here's an alternate solution that actually adds your certificate to the built in list of default certificates: Trusting all certificates using HttpClient over HTTPS

However, it will only work for your application. There's no way to programmatically do it for all applications on a user's device, since that would be a security risk.

你在看孤独的风景 2024-10-14 22:47:34

当我阅读问题的第一个答案 https://stackoverflow.com/a/22040887/19674027 我只是遵循了这个答案,但是就我而言,它不起作用完全按照 proxyman android 设置指南的回答
Proxyman>证书>在 Android 上安装证书>物理设备/模拟器>第 5 步

<network-security-config>
 <domain-config>
   <!-- Make sure your URL Server here -->
  <domain includeSubdomains="true">your_domain</domain>
  <trust-anchors>
   <certificates src="user"/>
   <certificates src="system"/>
  </trust-anchors>
</domain-config>

<debug-overrides>
 <trust-anchors>
   <certificates src="user" />
   <certificates src="system" />
 </trust-anchors>
</debug-overrides>

 <base-config cleartextTrafficPermitted="true">
   <trust-anchors>
    <certificates src="system" />
   </trust-anchors>
  </base-config>
</network-security-config>

,我按照 Android 设置指南中编写的 proxyman 进行了设置,并在此 res/xml/network_security_config.xml 中进行了一些更改,我使用了此代码片段。

<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
          <certificates src="user" />
        </trust-anchors>
     </base-config>
</network-security-config>

As i read first answer of question https://stackoverflow.com/a/22040887/19674027 i just followed this answer but in my case it's not worked exactly as proxyman android setup guide answered
Proxyman>Certificate>Install certificate on Android>Physical device/Emulator>step 5

<network-security-config>
 <domain-config>
   <!-- Make sure your URL Server here -->
  <domain includeSubdomains="true">your_domain</domain>
  <trust-anchors>
   <certificates src="user"/>
   <certificates src="system"/>
  </trust-anchors>
</domain-config>

<debug-overrides>
 <trust-anchors>
   <certificates src="user" />
   <certificates src="system" />
 </trust-anchors>
</debug-overrides>

 <base-config cleartextTrafficPermitted="true">
   <trust-anchors>
    <certificates src="system" />
   </trust-anchors>
  </base-config>
</network-security-config>

and i did setup as proxyman written in android setup guide with one changes in this res/xml/network_security_config.xml i used this code snippet.

<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
          <certificates src="user" />
        </trust-anchors>
     </base-config>
</network-security-config>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文