KeyPairGeneratorSpec Ersatz mit KeyGenParameterSpec.Generator-äquivalente - Keystore fehlgeschlagen
Folgende Methode ist veraltet
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
.setAlias(alias)
.setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
generator.initialize(spec);
Den Ersatz kam ich auf die wie folgt aussieht
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
generator.initialize(new KeyGenParameterSpec.Builder
(alias, KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA256)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.build());
Obwohl ich in der Lage bin, diese zu verwenden, erzeugen Sie ein Schlüsselpaar-Eintrag und verschlüsseln der Wert, ich bin nicht in der Lage es zu entschlüsseln
public void encryptString(String alias) {
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey();
String initialText = startText.getText().toString();
if(initialText.isEmpty()) {
Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show();
return;
}
//Security.getProviders();
Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);
cipherOutputStream.write(initialText.getBytes("UTF-8"));
cipherOutputStream.close();
byte [] vals = outputStream.toByteArray();
encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT));
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
public void decryptString(String alias) {
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
String cipherText = encryptedText.getText().toString();
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, 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();
}
String finalText = new String(bytes, 0, bytes.length, "UTF-8");
decryptedText.setText(finalText);
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
in der decrypt
Methode, den folgenden Befehl fehlschlägt:
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
mit
java.security.InvalidKeyException: Keystore operation failed
Ich denke, es hat zu tun mit der KeyGenParamaterSpec.Builder hat falsche Bedingungen, ähnlich wie die verschlüsseln-Chiffre-Typen falsch sind Zeichenfolgen, die gleiche Sache in die decrypt-Funktion.
Aber dies alles kann zurückgeführt werden auf die Verwendung der neuen KeygenParameterSpec.Generator, wie mit der älteren deprecated-Methode ermöglicht es mir, zu verschlüsseln und zu entschlüsseln.
Wie zu beheben?
- versuchen Ziel-android-18 -23, durch aufrufen keypairgeneratorspec.builder() und iam, der immer die Linie indivcating veraltet code? ich habe eine if-Anweisung targeting 18-23? wenn ich versuche, keygenparameterspec.- generator() iam immer einen compile-Zeit-Fehler rote Linie? sieht aus wie ive keine option, sondern auf die abgelehnte Anrufe? irgendwelche Vorschläge, anyone?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Alex erwähnt eine fehlende Stück ist
KeyProperties.PURPOSE_DECRYPT
andere istsetSignaturePaddings
statt für die, die Sie haben zu verwendensetEncryptionPaddings
Methode. Hier ist das Beispiel-snippet.Finden Dokumentation für weitere Informationen.
Es ist schwer zu 100% sicher sein, da Sie nicht bieten eine vollständige stack-trace der exception.
Ihren code generiert den privaten Schlüssel, so dass es nur berechtigt, das zum signieren verwendet werden, nicht entschlüsseln. Verschlüsselung funktioniert, weil es nicht mit dem private key -- es verwendet den öffentlichen Schlüssel und Android-Keystore öffentlichen Schlüssel können ohne Einschränkungen genutzt werden. Die Entschlüsselung schlägt fehl, weil es braucht, um den privaten Schlüssel nutzen, aber dein code nicht genehmigen die Nutzung der privaten Schlüssel für die Entschlüsselung.
Wie es aussieht ist die sofortige fix ist und zulassen, dass der private Schlüssel, der zur Entschlüsselung. Diese wird erreicht durch die Auflistung KeyProperties.PURPOSE_DECRYPT beim Aufruf der KeyGenParameterSpec.Generator-Konstruktor. Wenn der Schlüssel sollte nicht zum signieren verwendet werden, entfernen Sie KeyProperties.PURPOSE_SIGN von dort entfernen setSignaturePaddings.
Müssen Sie auch ermächtigen, den privaten Schlüssel verwenden, mit PKCS1Padding: invoke setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)