【问题标题】:Using Android's KeyChain API for exchanging public keys使用 Android KeyChain API 交换公钥
【发布时间】:2014-01-09 08:10:42
【问题描述】:

我正在尝试编写一个应用程序,使用户能够通过蓝牙/NFC 交换他们的公共(例如 RSA)密钥。要存储和稍后检索密钥,我想使用Android's KeyChain API.

到目前为止,我已经阅读了在线 API 文档和一些教程/示例。它们都涉及从包含私钥和相应公钥和证书的 PKCS12 文件导入钥匙串。导入此文件后,将返回别名字符串以供后续参考。到目前为止,一切顺利。

但是,我想要做的是接收某人的公钥,存储它,取回别名,将该别名存储在某处(例如联系人数据)并在用户想要加密消息时使用它来取回公钥给那个人。那可能吗?我对公钥密码学的经验很少,并且感觉我误解了 KeyChain API 的全部目的。

任何帮助将不胜感激!谢谢。

【问题讨论】:

    标签: android openssl rsa keychain pkcs#12


    【解决方案1】:

    Android KeyChain API 旨在存储 SSL 证书和密钥:安装 PKCS#12 或受信任的根证书颁发机构证书时您自己的密钥。然后,所有应用程序都可以使用此密钥和证书。

    这取决于您正在开发的应用程序的目的,但您可能应该考虑使用专用于您的应用程序的 KeyStore 来存储您收到的密钥,而不是 KeyChain API。

    API(KeyStore 和 KeyChain)的另一个限制是不能直接存储公钥。你需要有一个证书。我建议你在你的应用程序中嵌入一个自签名证书,并使用这个证书来签署包含应用程序将收到的公钥的“虚拟”证书。

    带有 bouncycastle 库的简化代码 sn-p 用于存储公共 RSA 密钥:

    public void storeRSAPublicKey(String alias, BigInteger modulus, BigInteger exponent) 
    {
        /** Load the key to generate the certificate */
        KeyStore ks = getApplicationKeyStore();
        KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)ks.getEntry(MY_PRIVATE_KEY, null);
        X509Certificate issuerCert = (X509Certificate)entry.getCertificate();
        PrivateKey skey = entry.getPrivateKey();
    
        /** Prepare the certificate template */
        RSAKeyParameters params = new RSAKeyParameters(false, modulus, exponent);
        SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfoFactory.SubjectPublicKeyInfo(params);
        X500Name issuer = new X500Name(issuerCert.getIssuerX500Principal().getName());
        X500Name subject = new X500Name("CN=alias");
        X509v3CertificateBuilder builder = new X509v3CertificateBuilder(issuer, randomSeriaNumber(), new Date(), dateIn20years(), subject, pkInfo);
    
        /** Generate the certificate */
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
        ContentSigner signer = csBuilder.build(skey);
        X509CertificateHolder holder = builder.build(signer);
    
        /** Store the certificate in the KeyStore */
        JcaX509CertificateConverter conv = new JcaX509CertificateConverter();
        X509Certificate cert = conv.getCertificate(holder);
        ks.setCertificateEntry(alias, cert);
        pushKeyStoreToPersistentStorage(ks);
    

    现在你可以通过ks.getCertificateEntry(alias);获得证书

    请注意,我省略了一些非基本代码,例如序列号生成和非过期日期计算。

    您可以使用keytool 创建初始 KeyStore,并将其作为资源添加到您的应用中。

    【讨论】:

      猜你喜欢
      • 2012-10-09
      • 2021-11-28
      • 2013-04-14
      • 2017-03-07
      • 1970-01-01
      • 2016-02-12
      • 2010-12-20
      • 2016-05-29
      • 1970-01-01
      相关资源
      最近更新 更多