[英]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.