从android密钥库中提取密钥对,并使用私钥加密数据

时间:2018-06-05 05:55:30

标签: java rsa private-key android-keystore encryption-asymmetric

当我在android中为RSA加密生成密钥对时,我能够使用公钥加密并使用私钥解密,反之亦然。以下是此工作代码。

.about {
  background-color: WhiteSmoke;
}

.about {
  padding: 3em 0;
}

.about p {
  text-align: left;
}

.about .row {
  margin-left: 0;
  margin-right: 0;
  width: 100%;
}

现在我想生成一个密钥对并将其存储在android密钥库中。该密钥对的目的是RSA加密和解密。我使用下面的代码:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    KeyPair kp = kpg.generateKeyPair();
    return kp;

我从android密钥库中检索上述密钥对,并且能够使用公钥加密并使用私钥解密。但是,当我尝试使用私钥加密时,我得到的是异常(对于android api> 22) -

public static AsymmetricKeyPair getKeyPair(Context context) throws Exception {
    AsymmetricKeyPair keyPair = new AsymmetricKeyPair();
    KeyPair kp = null;

    //Load Android Key Store
    KeyStore keyStore = KeyStore.getInstance(keyStoreProvider);
    keyStore.load(null);

    keyStore.deleteEntry(alias);

    boolean containsAlias = keyStore.containsAlias(alias);

    if (!containsAlias) {
        if (Build.VERSION.SDK_INT >= 23) {

            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 25);

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, keyStoreProvider);

            final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT |
                    KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                    .setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(keySize, RSAKeyGenParameterSpec.F4))
                    .setKeySize(keySize)
                    .setUserAuthenticationRequired(false)
                    .setKeyValidityEnd(end.getTime())
                    .setKeyValidityStart(start.getTime())
                    .setCertificateSerialNumber(BigInteger.ONE)
                    .setCertificateSubject(new X500Principal("CN=Auth0.Android,O=Auth0"))
                    .build();

            keyGen.initialize(keyGenParameterSpec);
            kp = keyGen.generateKeyPair();
            keyPair.setPrivateKey(kp.getPrivate());
            keyPair.setPublicKey(kp.getPublic());

        } else {

            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 25);

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, keyStoreProvider);

            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
                    .setAlias(alias)
                    .setKeySize(keySize)
                    .setKeyType(KeyProperties.KEY_ALGORITHM_RSA)
                    .setEndDate(end.getTime())
                    .setStartDate(start.getTime())
                    .setSerialNumber(BigInteger.ONE)
                    .setSubject(new X500Principal("CN=Auth0.Android,O=Auth0"))
                    .build();

            keyGen.initialize(spec);
            kp = keyGen.generateKeyPair();
            keyPair.setPrivateKey(kp.getPrivate());
            keyPair.setPublicKey(kp.getPublic());
        }
    } else {

        KeyStore.Entry entry = keyStore.getEntry(alias, null);
        if (entry instanceof KeyStore.PrivateKeyEntry) {
            PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
            PublicKey publicKey = keyStore.getCertificate(alias).getPublicKey();
            keyPair.setPrivateKey(privateKey);
            keyPair.setPublicKey(publicKey);
        }
    }
    return keyPair;
}

我要求使用“私钥”进行加密,尽管它不是首选。对于android api< = 22,它正在按预期工作。

加密和解密方法如下:

"java.security.InvalidKeyException:Keystore operation failed" Cause: "android.security.KeyStoreException: Incompatible purpose"

0 个答案:

没有答案