问题描述
如何将公钥 RSA 保存到“AndroidKeyStore”密钥库?
我开发了一个应用程序,该应用程序使用 RSA-AES 来加密两个对等方之间的数据。这有两个步骤,第一步是将公钥交换给其他对等方。然后使用AES会话密钥加密数据并使用RSA密钥加密AES会话密钥。 我研究了公钥可以与密钥存储中的证书一起保存,所以我执行以下代码:
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA,"AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder("key",KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setKeySize(2048)
.build());
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
Certificate x509Certificate = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(keyStore.getCertificate("key").getEncoded()));
keyStore.setCertificateEntry("key-new",x509Certificate);
Certificate certificate = keyStore.getCertificate("key-new");
当我getCertificate
(KeyStore:KeyStore异常
android.os.ServiceSpecificException: (代码 7))。
所以我编码错误,或者“AndroidKeyStore”不能用来保存其他人的公钥。
解决方法
我有两种使用 RSA 密钥加密和解密的方法,也许可以帮助您加密 AES 会话密钥。
private static final String ANDROID_KEY_STORE_NAME = "AndroidKeyStore";
private static final String KEY_ALIAS = "Milad";
private static final String RSA_MODE = "RSA/ECB/PKCS1Padding";
private static final String CIPHER_PROVIDER_NAME_ENCRYPTION_DECRYPTION_RSA = "AndroidOpenSSL";
private final Context mContext;
public Cryptography(Context context) {
mContext = context;
}
private byte[] rsaEncryptKey(byte[] secret) throws KeyStoreException,CertificateException,NoSuchAlgorithmException,IOException,NoSuchProviderException,NoSuchPaddingException,UnrecoverableEntryException,InvalidKeyException {
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_NAME);
keyStore.load(null);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS,null);
Cipher inputCipher = Cipher.getInstance(RSA_MODE,CIPHER_PROVIDER_NAME_ENCRYPTION_DECRYPTION_RSA);
inputCipher.init(Cipher.ENCRYPT_MODE,privateKeyEntry.getCertificate().getPublicKey());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream,inputCipher);
cipherOutputStream.write(secret);
cipherOutputStream.close();
byte[] encryptedKeyAsByteArray = outputStream.toByteArray();
return encryptedKeyAsByteArray;
}
private byte[] rsaDecryptKey(byte[] encrypted) throws KeyStoreException,null);
Cipher output = Cipher.getInstance(RSA_MODE,CIPHER_PROVIDER_NAME_ENCRYPTION_DECRYPTION_RSA);
output.init(Cipher.DECRYPT_MODE,privateKeyEntry.getPrivateKey());
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(encrypted),output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte) nextByte);
}
byte[] decryptedKeyAsBytes = new byte[values.size()];
for (int i = 0; i < decryptedKeyAsBytes.length; i++) {
decryptedKeyAsBytes[i] = values.get(i);
}
return decryptedKeyAsBytes;
}