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

Ran*_*med 5 android rsa public-key-encryption android-keystore

服务器端应用程序生成一个RSA密钥对,作为密钥交换过程的一部分,我从服务器获取此公钥,现在我想将此密钥存储在android KeyStore中.我已经看到了使用KeyGenerator生成rsa密钥对并将它们存储在android KeyStore中的示例,但我不知道如何存储已生成的RSA公钥.任何帮助将受到高度赞赏.

Jam*_*olk 6

我不确定哪些部分让您感到困惑,或者您到底想要实现什么目标。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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)