代码之家  ›  专栏  ›  技术社区  ›  Raneez Ahmed

如何在服务器端应用程序生成的Android密钥库中存储和检索RSA公钥?

  •  7
  • Raneez Ahmed  · 技术社区  · 7 年前

    服务器端应用程序生成一个RSA密钥对,作为密钥交换过程的一部分,我从服务器获取此公钥,现在我想将此密钥存储在android密钥库中。我见过使用KeyGenerator生成rsa密钥对并将其存储在android密钥库中的示例,但我不知道如何存储已生成的rsa公钥。任何帮助都将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  4
  •   President James K. Polk    7 年前

    我不确定哪些部分让你困惑,或者你到底想实现什么。 KeyStore 只能保存三种类型的条目:对称密钥、私钥和证书。因此,如果要存储公钥,必须将其格式化为证书。应用程序是否使用X509证书的任何其他功能取决于您。

    还不清楚您是否要在Android上使用任何旧密钥库,或者 这个 AndroidKeyStore 。后者提供了增强的功能,但您是否需要它们取决于您的威胁模型。无论如何,这里有一个示例显示如何将google公钥导入Android密钥库,如何在其上设置一些属性,以及如何使用它加密AES密钥。

    import android.security.keystore.KeyProperties;
    import android.security.keystore.KeyProtection;
    import android.util.Base64;
    import android.util.Log;
    
    import java.io.ByteArrayInputStream;
    import java.nio.charset.StandardCharsets;
    import java.security.Key;
    import java.security.KeyStore;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String THE_CERT = "-----BEGIN CERTIFICATE-----\n" +
                "MIIIPjCCByagAwIBAgIIWcyJ5Cnzp3UwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE\n" +
                "BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl\n" +
                "cm5ldCBBdXRob3JpdHkgRzIwHhcNMTgwMzEzMTgzMDQ1WhcNMTgwNjA1MTgxNjAw\n" +
                "WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN\n" +
                "TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEVMBMGA1UEAwwMKi5n\n" +
                "b29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtXqeeS6r\n" +
                "sLfE5dx5asD7dngw0Dev9rhgDYM9kAuV9VxbZJ2ehZM4Nk1zGGSlqidgRWsVSNrx\n" +
                "qb513IyrtxDSvTTGh8ihFGNTL/H61e+cYU565RCw4siOU0IevyhynPVh8D38pe5U\n" +
                "bkGDmkiP7tOVozQE+3Q7l6xaIvlq9hIAb0aTWdJ6AOm3r/iMRdiUv/kxIienQ4v/\n" +
                "RY/h3K/llz1E+S+TAyM2+As8o2nRMGrp9/hg8zIs3CLLv2km9VS/fgTQrM5pcfDf\n" +
                "iX6Tgzb+6RSGHnT7GgNA3R1LXo96gnwf3zlX3SqpvV8pQf2Y3TxhLRB7J28yZFef\n" +
                "P6d9t2EqlHZv+wIDAQABo4IFCzCCBQcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwggPh\n" +
                "BgNVHREEggPYMIID1IIMKi5nb29nbGUuY29tgg0qLmFuZHJvaWQuY29tghYqLmFw\n" +
                "cGVuZ2luZS5nb29nbGUuY29tghIqLmNsb3VkLmdvb2dsZS5jb22CFCouZGI4MzM5\n" +
                "NTMuZ29vZ2xlLmNuggYqLmcuY2+CDiouZ2NwLmd2dDIuY29tghYqLmdvb2dsZS1h\n" +
                "bmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xl\n" +
                "LmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xl\n" +
                "LmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29v\n" +
                "Z2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyou\n" +
                "Z29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2ds\n" +
                "ZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5n\n" +
                "b29nbGUucGyCCyouZ29vZ2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22CDyouZ29v\n" +
                "Z2xlYXBpcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CESouZ29vZ2xldmlkZW8u\n" +
                "Y29tggwqLmdzdGF0aWMuY26CDSouZ3N0YXRpYy5jb22CCiouZ3Z0MS5jb22CCiou\n" +
                "Z3Z0Mi5jb22CFCoubWV0cmljLmdzdGF0aWMuY29tggwqLnVyY2hpbi5jb22CECou\n" +
                "dXJsLmdvb2dsZS5jb22CFioueW91dHViZS1ub2Nvb2tpZS5jb22CDSoueW91dHVi\n" +
                "ZS5jb22CFioueW91dHViZWVkdWNhdGlvbi5jb22CByoueXQuYmWCCyoueXRpbWcu\n" +
                "Y29tghphbmRyb2lkLmNsaWVudHMuZ29vZ2xlLmNvbYILYW5kcm9pZC5jb22CG2Rl\n" +
                "dmVsb3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdv\n" +
                "b2dsZS5jboIEZy5jb4IGZ29vLmdsghRnb29nbGUtYW5hbHl0aWNzLmNvbYIKZ29v\n" +
                "Z2xlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghhzb3VyY2UuYW5kcm9pZC5nb29n\n" +
                "bGUuY26CCnVyY2hpbi5jb22CCnd3dy5nb28uZ2yCCHlvdXR1LmJlggt5b3V0dWJl\n" +
                "LmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb22CBXl0LmJlMGgGCCsGAQUFBwEBBFww\n" +
                "WjArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcyLmNydDAr\n" +
                "BggrBgEFBQcwAYYfaHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20vb2NzcDAdBgNV\n" +
                "HQ4EFgQU2Xh9D7F5dJYCBqsWcKChI16NReswDAYDVR0TAQH/BAIwADAfBgNVHSME\n" +
                "GDAWgBRK3QYWG7z2aLV29YG2u2IaulqBLzAhBgNVHSAEGjAYMAwGCisGAQQB1nkC\n" +
                "BQEwCAYGZ4EMAQICMDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9wa2kuZ29vZ2xl\n" +
                "LmNvbS9HSUFHMi5jcmwwDQYJKoZIhvcNAQELBQADggEBAFxBsH2U6j4KzZbNcyN1\n" +
                "UGiJnMn64DIXH8wsWrFEGAq3ONRhPgKd3AnbaBUdNdrRgOhfA3RtLvvnxsKn0rX6\n" +
                "Oz8+p5DZxJooUgWlet9NounLDe5um6m5NqLIGefdI49Ukn6IwBtCO5DD7rZTygTa\n" +
                "B499H9N0ixI9wGBdlZ37tOpCxayNb08eizU1uQEhb1/oxnXf0e6trPfC8krDL0Ks\n" +
                "Pyf3JgB5oBTiNAfix2zme1FrpXcKehOj2urnLQRr5EpminCJ+0uHI1sqiJbcSHrU\n" +
                "6TPQcOzZ7/haw1yY2bpy+sB4oXUMaNJxh6e2AiCeVf4MtX9EsYEnhsfc2XS50J32\n" +
                "nKo=\n" +
                "-----END CERTIFICATE-----";
    
        private void doExample() {
            try {
                X509Certificate googleCert = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(THE_CERT.getBytes(StandardCharsets.UTF_8)));
                KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
                KeyProtection keyProtection = new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_VERIFY)
                        .setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256)
                        .setRandomizedEncryptionRequired(true)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                        .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
                        .setUserAuthenticationRequired(false)
                        .build();
                keyStore.load(null);
                keyStore.setEntry("googlecert", new KeyStore.TrustedCertificateEntry(googleCert), keyProtection);
                // Now use the entry
                KeyGenerator aesKeygen = KeyGenerator.getInstance("AES");
                aesKeygen.init(128);
                Key aesKey = aesKeygen.generateKey();
                // Wrap key for transport
                KeyStore keyStore2 = KeyStore.getInstance("AndroidKeyStore");
                keyStore2.load(null);
                Certificate googleCert2 = keyStore2.getCertificate("googlecert");
                Cipher rsaCipher = Cipher.getInstance("RSA/ECB/OAEPwithSHA-256andMGF1Padding");
                rsaCipher.init(Cipher.WRAP_MODE, googleCert2);
                byte[] rsaEncrypted = rsaCipher.wrap(aesKey);
                Log.d("crypt", Base64.encodeToString(rsaEncrypted, Base64.DEFAULT));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }