6

Ich versuche, Strings in meiner Android-Anwendung zu verschlüsseln und zu entschlüsseln, aber ich bekomme immer eine InvalidKeyException-Fehler.Android Entschlüsselungsfehler

ist hier mein Code:

// Gene Keys Methode

public void generateKeys() { 
    Calendar cal = Calendar.getInstance(); 
    Date now = cal.getTime(); 
    cal.add(Calendar.YEAR, 25); 
    Date end = cal.getTime(); 

    KeyPairGenerator kpg = null; 
    try { 
     kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (NoSuchProviderException e) { 
     e.printStackTrace(); 
    } 
    try { 
     kpg.initialize(new KeyPairGeneratorSpec.Builder(context) 
       .setAlias(KEY_ALIAS) 
       .setStartDate(now) 
       .setEndDate(end) 
       .setSerialNumber(BigInteger.valueOf(1)) 
       .setSubject(new X500Principal("CN=" + KEY_ALIAS)) 
       .build()); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 

    KeyPair kp = kpg.generateKeyPair(); 

    KeyStore ks = null; 
    try { 
     ks = KeyStore.getInstance("AndroidKeyStore"); 
     ks.load(null); 
     Enumeration<String> aliases = ks.aliases(); 
    } catch (KeyStoreException e) { 
     e.printStackTrace(); 
    } catch (CertificateException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    KeyStore.Entry entry = null; 
    try { 
     entry = ks.getEntry(KEY_ALIAS, null); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (UnrecoverableEntryException e) { 
     e.printStackTrace(); 
    } catch (KeyStoreException e) { 
     e.printStackTrace(); 
    } 
    if (!(entry instanceof KeyStore.PrivateKeyEntry)) { 
     Log.e(LOG_TAG, "Not an instance of PrivateKeyEntry."); 
    } 
    else{ 
     privKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); 
     pubKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); 
    } 

} 

// Encrypt-Methode

private String encryptString(String value){ 
    byte[] encodedBytes = null; 
    try { 
     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); 
     cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
     encodedBytes = cipher.doFinal(value.getBytes()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return Base64.encodeToString(encodedBytes, Base64.DEFAULT); 
} 

// Decrypt Methode

private String decryptString(String value){ 
    byte[] decodedBytes = null; 
    try { 
     Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); 
     c.init(Cipher.DECRYPT_MODE, privKey); 
     decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e("Error", "Error = " + e); 
     return "SECURE_FAILURE"; 
    } 

    return new String(decodedBytes); 
} 

// Prüft Code

generateKeys(); 
    String encrypted = encryptString("Hello World"); 
    Log.e("Encrypt", "encrypted = " + encrypted); 
    String decrypted = decryptString(encrypted); 
    Log.e("Decrypt", "decrypted = " + decrypted); 

Es sieht aus wie die Verschlüsselung OK funktioniert, wie es so etwas wie dieses ausdruckt:

encrypted = SbA2iWWKQbDL7NTA9xvtjD/viYDdpx9fLRYTSZ8UQzdBy3QLqzkswBY21ErH7FPza3vZys4E4PZw uxaGkRz0aC0FLqsYlbpcJernGm5+D5lRcBOaZmgkNY9pMf0YP75cBbcJdcmb1rDaH40nCRDnEoXv rGESJRqT6p0NMzlZqdd9KO3tqfExwgservAWxPNtRDBbMgE4I/09418jM5Ock5eayfOuv/STwEy6 Ecd56UjFH63h+gP6ed2aMDhBVeExMxvdloY+VnsAxS5Dkoc2GdaljtjRuPK48HQASoJK8EwAMNpz

Aber wenn ich versuche ich die folgende Fehlermeldung erhalten zu entschlüsseln:

java.security.InvalidKeyException: Need RSA private or public key

kann ich Warum sehe ich diese Ausnahme nicht? Kann jemand helfen?

+0

Irgendwas Glück? Ich bekomme die gleiche Ausnahme in Android Marshmallow. – Luis

+0

Ich habe es mit einem anderen Provider behoben ... siehe meine Antwort unten. – Luis

+1

Wenn es keinen Grund gibt, asymmetrische Verschlüsselung (RSA) zu benötigen, verwenden Sie öffentliche/private Schlüssel nur mit symmetrischer Verschlüsselung wie AES. Symmetrische Verschlüsselung ist die allgemeine Wahl für die Datenverschlüsselung. Die Länge der asymmetrischen Verschlüsselungsdaten ist auf die Schlüsselgröße beschränkt und ist sehr langsam und nicht sicherer. – zaph

Antwort

9

Versuchen Sie einen anderen Anbieter verwenden, wie folgt aus:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); 
+2

Funktioniert für mich, obwohl einige Erklärung großartig wäre. – Waboodoo

8

dies für mich gearbeitet:

private Cipher getCipher() { 
    try { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m 
      return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); // error in android 6: InvalidKeyException: Need RSA private or public key 
     } 
     else { // android m and above 
      return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround 
     } 
    } catch(Exception exception) { 
     throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception); 
    } 
} 
2

Entfernen der Anbieter für mich gearbeitet:

Cipher.getInstance("RSA/ECB/PKCS1Padding") 

Von Java docs: " Diese Methode durchläuft die Liste der registrierten Sicherheitsanbieter, beginnend mit dem bevorzugten Provider pher-Objekt, das die CipherSpi-Implementierung vom ersten Provider einkapselt, der den angegebenen Algorithmus unterstützt, wird zurückgegeben. "