繁体   English   中英

是否可以在没有 P12 的情况下向 Android 上的 KeyChain 添加私钥 + 证书?

[英]Is it possible to add a Private Key + Certificate to the KeyChain on Android without a P12?

以下代码允许我向KeyChain添加一个 PKCS12 文件,效果很好:

val pkcs12Bytes = pkcs12Location.readBytes()
val installIntent = KeyChain.createInstallIntent()
installIntent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12Bytes)
startActivity(installIntent)

但是,出于安全原因,我希望在没有在设备上存储 P12 的情况下将私钥和证书添加到KeyChain 私钥由keyGen.generateKeyPair()创建后存储在 memory 中。

这是我在使用 P12 实现时得到的弹出窗口(注意“一个用户密钥”):

在此处输入图像描述


到目前为止,我已经能够使用此代码向KeyChain添加证书

val installIntent = KeyChain.createInstallIntent()
installIntent.putExtra(KeyChain.EXTRA_CERTIFICATE, x509Certificate)
startActivity(installIntent)

但我找不到将私钥包含在文档中的方法。 是否可以在没有 P12 的情况下将私钥 + 证书添加到 Android 上的钥匙串?

这是我在使用证书实现时得到的弹出窗口(仅注意证书):

在此处输入图像描述

获得创意后,答案

似乎不可能完全绕过KeyChain.EXTRA_PKCS12方法,但我确实找到了一种将 P12 存储在 memory 中的方法,这样它就不会存储在 Android 的文件系统中。 这种方式比将其存储在文件系统上更安全,但仍然不如我们能够将私钥和证书直接添加到KeyChain中那样安全。

这是我用来在 memory 而不是在文件系统上创建 PKCS12 的方法:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public static byte[] createPKCS12InMemory(byte[] x509AsPEM, PrivateKey privKey, String pkcs12Password) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
    InputStream stream = new ByteArrayInputStream(x509AsPEM);
    CertificateFactory fact = CertificateFactory.getInstance("X.509");
    X509Certificate cert = (X509Certificate) fact.generateCertificate(stream);
    KeyStore pkcs12 = KeyStore.getInstance("PKCS12");
    pkcs12.load(null, null);
    pkcs12.setKeyEntry("device_certificate", privKey, pkcs12Password.toCharArray(), new Certificate[] {cert});
    ByteArrayOutputStream p12 = new ByteArrayOutputStream();
    pkcs12.store(p12, pkcs12Password.toCharArray());
    return p12.toByteArray();
}

一旦您将 PKCS12 作为 memory 中的字节,您可以将其直接传递到installIntent中,实际上永远不会在文件系统上存储 p12!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM