读取 Android 应用程序的 PKCS12/P12 客户端证书文件

2023-12-04

我正在尝试在我的 Android 应用程序中使用客户端证书,以便我可以确保仅与使用该应用程序或拥有该证书的人进行 HTTPS 通信。

我的 res/raw 文件夹中有证书。当我开始输入“R.raw”时,Android Studio 就会看到它。

但是,当我使用以下任何代码时,变量返回为具有“null”值:

FileInputStream fis = null;
fis = (FileInputStream) getClass().getResourceAsStream(String.valueOf(R.raw.clientcert2));

or

InputStream fis = getClass().getResourceAsStream("raw/clientcert2.p12");

or

InputStream fis = null;
fis= (InputStream) getResources().openRawResource(R.raw.clientcert2);

最后一个实际上使应用程序崩溃了,这让我认为它甚至不接近正确。它因以下错误而崩溃:

09-10 08:13:06.677  10310-10310/com.example.agenice.clientcert E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.agenice.clientcert, PID: 10310
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.agenice.clientcert/com.example.agenice.clientcert.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:78)
at com.example.agenice.clientcert.GetCert.getThisCert(MainActivity.java:92)
at com.example.agenice.clientcert.MainActivity.onCreate(MainActivity.java:58)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

作为旁注 - 是的,我知道如果有人获得 APK,他们可以简单地解压缩包并获取证书。这就是为什么这不是应用程序的最终形式。这只是该过程的第一步。在 iOS 版本的应用程序中,我能够导入 p12 文件,将二进制文件转换为字符串,将字符串导出到日志,然后将其用作证书。这消除了将证书文件添加到应用程序的需要。所以,这就是整个事情的发展方向。如果有人有一种快速而简单的方法来做到这一点,那就太好了。现在,我需要的只是弄清楚为什么这部分不起作用。

Thanks!


为您更新NullPointerException

从你的logcat信息,getResources() in GetCert.getThisCert()导致 NullPointerException。看来你还没有通过Context从你的Activity to GetCert班级。因此,请更新您的代码并检查结果。

更新结束

你可以参考我下面的代码:

private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
        return new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return originalTrustManager.getAcceptedIssuers();
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkClientTrusted(certs, authType);
                        } catch (CertificateException e) {
                            e.printStackTrace();
                        }
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkServerTrusted(certs, authType);
                        } catch (CertificateException e) {
                            e.printStackTrace();
                        }
                    }
                }
        };
    }

private SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
        throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = getResources().openRawResource(keystoreResId);

    Certificate ca = cf.generateCertificate(caInput);
    caInput.close();

    if (keyStoreType == null || keyStoreType.length() == 0) {
        keyStoreType = KeyStore.getDefaultType();
    }
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, wrappedTrustManagers, null);

    return sslContext.getSocketFactory();
}

private SSLSocketFactory getSSLSocketFactory_KeyStore(String keyStoreType, int keystoreResId, String keyPassword)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

        InputStream caInput = getResources().openRawResource(keystoreResId);

        // creating a KeyStore containing trusted CAs

        if (keyStoreType == null || keyStoreType.length() == 0) {
            keyStoreType = KeyStore.getDefaultType();
        }
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);

        keyStore.load(caInput, keyPassword.toCharArray());

        // creating a TrustManager that trusts the CAs in the KeyStore

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, wrappedTrustManagers, null);

        return sslContext.getSocketFactory();
    }

然后调用以下两个之一(一个用于密钥库文件,另一个用于证书文件):

SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("BKS", R.raw.androidbksv1, "123456789");
SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("BKS", R.raw.androidbksv1_cert);

因为你有PKCS12文件,您可以使用以下两个之一:

SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("PKCS12", R.raw.androidpkcs12, "123456789");        
SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("PKCS12", R.raw.androidpkcs12_cert);

上面的代码已经在我的HTTPS项目中测试成功。希望这可以帮助!

另外,请澄清一下The last one actually crashes the app...,发布更多代码和 logcat 信息(如果有)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读取 Android 应用程序的 PKCS12/P12 客户端证书文件 的相关文章

随机推荐

  • 如何使用 matlab 从 yuv 420 视频剪辑中提取帧并将它们存储为不同的图像?

    如何从 yuv 420 视频中提取帧 假设我想将它们存储为静态图像 如何 这是来自MathWorks 文件交换那应该做你想做的事 将 YUV CIF 4 2 0 视频文件转换为图像文件 by Da Yu 功能loadFileYuv从上面的提
  • 中的每个文件创建 FormData 实例

    我正在尝试使用输入文件multiple属性并拆分 formData 这样我就可以为多文件元素中的每个文件提供一个 formData HTML
  • 使用 ITextSharp 创建可填写的 PDF 表单

    我使用 Acrobat Adob e 8 创建了一个包含可填写字段的 PDF 文件 可以使用 ITextSharp 而不是 Adob e 进行编程吗 注意 我并不是指使用 ITextSharp 填写 PDF 而是我想create使用 ITe
  • 将时区添加到 data.table 中的 POSIXct 对象

    我有一个 data table 对象 其中日期和时间列存储为 IDate ITime 对象 我还有一个时区列 其中时区以字符形式给出 现在我想创建一个使用 POSIXct 格式的 DateTime 列 但是我不知道如何向对象添加正确的时区
  • 有没有办法判断 python 是否使用“--with-threads --enable-shared”进行配置和编译?

    这是针对 Debian Squeeez 上的 Python 2 6 6 我试图查明 debian 附带的二进制文件是否配置了以下标志 with threads enable shared 就好像它们不是一样 我需要自己从源代码编译和安装 w
  • Solidity 中的动态数组

    我想声明一个简单的数组 动态列表 一个set函数推入一个字符串和一个get函数返回动态数组中保存的所有字符串 我搜索了很多但找不到这个简单的东西 这是我的解决方案 你需要experimental ABIEncoderV2返回字符串数组 pr
  • 如何在 DASH 内容的

    我已使用以下方式在网页中嵌入了 DASH 视频
  • ID/类别选择器

    我对 jQuery 选择器有一些问题 假设我想选择 elementID 但是elementID是一个变量 除了以其他方式执行此操作之外 还有其他可能性var variable elementID variable 我的意思是没有指定 还有其
  • 扩展并仅指定已知属性?

    我试图提供一个接受给定类型的映射的接口 并将其用于运行时逻辑和编译时类型 就像是 type SomeType a string b a string b string magicalFunction a 1 1 return type is
  • 在 __init__ 中使用继承的类方法

    我有一个由几个孩子继承的父类 我想使用父母的初始化其中一个孩子 classmethod初始化器 我怎样才能做到这一点 我试过 class Point object def init self x y self x x self y y cl
  • 如何像Xcode一样绘制带有蓝色色调的分段控件?

    我正在尝试重新创建 Xcode 中使用的分段控件 其中图像用蓝色绘制 例如在界面生成器中 到目前为止我有一个习惯NSSegmentedCell压倒性的 void drawSegment NSInteger segment inFrame N
  • 如何使用 Javascript 从 Google Api 检索服务帐户 OAuth2 令牌?

    我需要使用 google 项目服务帐户来使用 JavaScript 访问 google API 为了做到这一点 我需要 OAuth2 到 google API 服务器来获取身份验证令牌 据我所知 Google 提供了一个用于节点服务器的库
  • 检查字符串中是否有以字符 @ 开头的单词

    您好 感谢您花时间调查此问题 我正在开发一个评论系统 而不是使用嵌套评论 我只想添加 user 方法进行回复 举例来说 我输入了以下评论 moonwalker Thanks again for your reply 我正在寻找一个函数来检查
  • Git WebHook 不会拉取 (PHP)

    我有一个 PHP 文件 hook php 看起来像这样
  • 如何在Python中保存二维数组(列表)?

    我需要将表示游戏世界中的地图的二维数组保存到配置解析器中 数据如下 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 举个例子 我显然可以保存数据 但在读回数据后无法将其从字符串转换回列表 顺便说一句 我不介意是否必须使用 txt
  • 带有 templateUrl 和 ng-repeat 的自定义指令

    我已经研究这个问题几个小时了 终于我在 plunker 上复制了它 这是我的问题 当使用外部资源作为模板的自定义指令与 ng repeat 结合使用时 模型更改时视图无法正确渲染 在我的示例中 单击链接将替换模型 但旧数据尚未清除 如果我使
  • 将字符串列表与可用的字典/同义词库进行比较

    我有一个程序 C 它生成一个字符串列表 原始字符串的排列 大多数字符串是按预期随机分组的原始字母 即 etam aemt team 我想以编程方式找到列表中真正的英语单词的一个字符串 我需要一个同义词库 字典来查找和比较每个字符串 任何人都
  • 将 CSS/HTML 中的按钮与文本水平对齐一行?

    我想知道如何水平对齐按钮 最重要的是 我想向这些按钮添加文本 这就是我目前所拥有的 HTML 正文部分 div class tile div table class tile table tr td img class tile image
  • CSS 内部 id 选择器

    我在 CSS 文件中有以下 id 选择器 headerphoto 和 logo box 是 header id 的内部 id 选择器 我真的需要将这两个添加为内部 id 选择器吗 我可以将它们添加为普通的 id 选择器 这样做的最佳方法是什
  • 读取 Android 应用程序的 PKCS12/P12 客户端证书文件

    我正在尝试在我的 Android 应用程序中使用客户端证书 以便我可以确保仅与使用该应用程序或拥有该证书的人进行 HTTPS 通信 我的 res raw 文件夹中有证书 当我开始输入 R raw 时 Android Studio 就会看到它