studio library example cipher cbc java android encryption cryptography aes-gcm

java - library - GCMParameterSpec throws InvalidAlgorithmParameterException: tipo de parámetro desconocido



cipher android example (2)

prueba este código ...

private static final String Key = "0123456789abcdef"; public static SecretKey generateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException { return new SecretKeySpec(Key.getBytes("UTF-8"), "AES"); } public static byte[] encryptMsg(String message, SecretKey secret) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { Cipher cipher; cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); return cipher.doFinal(message.getBytes("UTF-8")); } public static String decryptMsg(byte[] cipherText, SecretKey secret) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { Cipher cipher; cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret); return new String(cipher.doFinal(cipherText), "UTF-8"); }

Estoy haciendo encriptación de datos android para guardar en SharedPreferences. GCMParameterSpec se introdujo en Android en la API 19 que estoy usando para el AES/GCM/NoPadding . Así es como lo estoy implementando:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding"); c.init(Cipher.ENCRYPT_MODE, getSecretKey(context),new GCMParameterSpec(128,Base64.decode(myGeneratedIV, Base64.DEFAULT)));

Mi problema es que en Android 4.4.2 (API 19) aparece el error mencionado, pero desde la API 21 funciona.

Acerca de la excepción, de los documentos de Android:

si los parámetros del algoritmo dados son inapropiados para este cifrado, o este cifrado requiere parámetros del algoritmo y params es nulo, o los parámetros del algoritmo dados implican una fuerza criptográfica que excedería los límites legales (según lo determinado por los archivos de política de jurisdicción configurados).

Mi pregunta es: ¿hay alguna razón específica para este comportamiento? ¿Por qué el método init de Cipher no identifica los params?

Incluso intenté encriptar sin dar una IV específica:

c.init(Cipher.ENCRYPT_MODE, getSecretKey(context));

Y una vez que intenté descifrar de la misma manera:

c.init(Cipher.DECRYPT_MODE, getSecretKey(context));

Lanza la misma excepción (InvalidAlgorithmParameterException) diciendo que un GCMParameterSpec es necesario para el descifrado.

Traté de dar el GCMParameterSpec solo para el descifrado, y obtengo la excepción de tipo de parámetro desconocido.

Cualquier ayuda es apreciada


Es posible que la implementación de CipherSpi en el proveedor de Android aún no sea compatible con GCMParameterSpec . Definir una API no es lo mismo que brindarle soporte dentro del proveedor de criptografía subyacente.

En su lugar, puede utilizar el estándar IvParameterSpec proporcionado para los otros modos también. Simplemente use los (12) bytes IV / nonce para su GCMParamterSpec directamente como su IV.

Como tiene el tamaño de etiqueta estándar, esto no debería representar ningún problema con su implementación.

En caso de que el tamaño de la etiqueta difiera, la solución se vuelve más complicada ya que la verificación solo usará los bytes más a la izquierda de la etiqueta resultante. Lamentablemente, la generación y verificación de etiquetas está oculta dentro del diseño API de la clase Cipher .