我需要使用API 18将敏感数据存储在本地存储中,我选择使用Keystore。我尝试了几种解决方案,但都没有用。
我尝试在不进行强制转换的情况下在PrivateKey中创建我的RSAPrivateKey,但是它不起作用。 我也尝试使用其他加密算法,但是我无法成功使它们在API 18中工作
public String decryptString(String alias, String encryptedText) {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
String decryptedText = "";
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKey);
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(encryptedText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
decryptedText = new String(bytes, 0, bytes.length, "UTF-8");
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return decryptedText;
}
public String encryptString(String alias, String initialText) {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
String encryptedText = "";
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey();
// Encrypt the text
if(initialText.isEmpty()) {
Log.e(TAG, "initialText is Empty");
return "";
}
Cipher input = Cipher.getInstance("RSA/ECB/PKCS1Padding");
input.init(Cipher.ENCRYPT_MODE, publicKey);//Need RSA private or public key
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, input);
cipherOutputStream.write(initialText.getBytes("UTF-8"));
cipherOutputStream.close();
byte [] vals = outputStream.toByteArray();
encryptedText = Base64.encodeToString(vals, Base64.DEFAULT);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return encryptedText;
}
这是我得到的性爱。我想成功地将数据保存在安全的地方
java.security.InvalidKeyException: Unsupported key algorithm: EC. Only RSA supported
at com.cryptor.Cryptor.encryptString(Cryptor.java:108)
答案 0 :(得分:0)
当您生成RSA密钥时,我看不到哪里。就我而言,我已完成以下步骤:
Keystore
KeyPairGenerator
生成RSA密钥(请注意:自Android M起采用不同的方法) val generator = KeyPairGenerator.getInstance(ALGORITHM, CryptoConstants.ANDROID_KEY_STORE)
在这里, ALGORITHM =“ RSA” ,而不是“ RSA / ECB / PKCS1Padding”和CryptoConstants。ANDROID_KEY_STORE=“ AndroidKeyStore”(例如)
Keystore
通过这些步骤,我的加密方法是
fun encrypt(publicKey: PublicKey, rawText: ByteArray): String {
try {
val cipher = CipherUtil.getStandardCipherInstance(TRANSFORMATION) // TRANSFORMATION = "RSA/ECB/PKCS1Padding"
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val bytes = cipher.doFinal(rawText)
return Base64.encodeToString(bytes, BASE64_SETTINGS) // BASE64_SETTINGS = Base64.NO_WRAP
} catch (e: GeneralSecurityException) {
throw SecurityException(e)
}
}
fun decrypt(privateKey: PrivateKey, base64CipherBytes: ByteArray): ByteArray {
try {
val cipher = CipherUtil.getStandardCipherInstance(TRANSFORMATION) // TRANSFORMATION = "RSA/ECB/PKCS1Padding"
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val encryptedData = Base64.decode(base64CipherBytes, BASE64_SETTINGS) // BASE64_SETTINGS
return cipher.doFinal(encryptedData)
} catch (e: GeneralSecurityException) {
throw SecurityException(e)
}
}
顺便说一句,如果不需要,您可以绕过Base64编码。