Error de descifrado de Android

Estoy tratando de cifrar y descifrar cadenas en mi aplicación de Android, pero sigo recibiendo un error InvalidKeyException.

Aquí está mi código:

// Generar método Keys

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(); } } 

// Encriptar método

 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); } 

// Descifrar el método

 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); } 

// Código de prueba

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

Parece que el cifrado funciona bien, ya que imprime algo como esto:

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

Pero cuando intento descifrar consigo el error siguiente:

Java.security.InvalidKeyException: Necesita una clave privada o pública RSA

No puedo entender por qué estoy recibiendo esta excepción? ¿Alguien puede ayudar?

Intente usar un proveedor diferente, como esto:

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

Esto funcionó para mí:

  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); } } 

Quitar el proveedor funcionó para mí:

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

Desde documentos Java : "Este método atraviesa la lista de proveedores de seguridad registrados, comenzando con el proveedor más preferido. Se devuelve un nuevo objeto Cipher que encapsula la implementación CipherSpi del primer proveedor que admite el algoritmo especificado."

  • ACTUALIZADO: Android: java.lang.RuntimeException: No se puede iniciar la actividad ComponentInfo
  • Error de método de reflexión de Android
  • Configuración de Proguard para Android Support v4 22.2.0
  • Typed Array debe ser reciclado después de su uso con #recycle ()
  • ¿Cómo leer un archivo de texto del directorio "assets" como una cadena?
  • Android nunca recibe paquetes UDP
  • Cómo utilizar interceptor para agregar encabezados en Retrofit 2.0
  • Compruebe si DAY_OF_WEEK es entre el lunes y el viernes
  • Acceso al dispositivo mtp con java
  • Animación de carga de Android
  • ¿Cómo devuelvo un booleano de AsyncTask?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.