Uso de cifrado basado en contraseña en android
El código a continuación, aunque funciona, pero cuando ejecuto continuamente tiros "Dado bloque final no correctamente acolchado" algunas veces y otros también. Siento que estoy haciendo un pequeño error en algún lugar. ¿Puede ayudarme a resolver el problema?
Pila de excepciones:
- Cifrado con AES-256 y el vector de inicialización
- ¿Dónde guardamos key / passphrase / salt para el cifrado?
- Descodificación lenta de AES en Android
- Práctica recomendada para descifrar archivos grandes con menos memoria
- ¿Cómo instalar SunJCE en Android?
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811) at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) at javax.crypto.Cipher.doFinal(Cipher.java:2086) at MCrypt.decrypt(MCrypt.java:87) at MCrypt.main(MCrypt.java:21)
Y mi código:
import java.security.SecureRandom; import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; public class MCrypt { private int iterationCount = 10000; private int saltLength = 8; // bytes; 64 bits private int keyLength = 128; public static void main(String[] args) throws Exception { MCrypt mc = new MCrypt(); String encryptedData = mc.encrypt("1234"); MCrypt mc1 = new MCrypt(); System.out.println(new String(mc1.decrypt(new String(encryptedData), "1234"), "UTF-8")); } public MCrypt() { } public String encrypt(String text) throws Exception { if (text == null || text.length() == 0) throw new Exception("Empty string"); byte[] encrypted = null; SecureRandom random = new SecureRandom(); byte[] salt = new byte[saltLength]; random.nextBytes(salt); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] iv = new byte[cipher.getBlockSize()]; random.nextBytes(iv); IvParameterSpec ivParams = new IvParameterSpec(iv); KeySpec keySpec = new PBEKeySpec(text.toCharArray(), salt, iterationCount, keyLength); SecretKeyFactory keyFactory = SecretKeyFactory .getInstance("PBKDF2WithHmacSHA1"); byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); SecretKey key = new SecretKeySpec(keyBytes, "AES"); cipher.init(Cipher.ENCRYPT_MODE, key, ivParams); encrypted = cipher.doFinal(text.getBytes("UTF-8")); String encryptedStr = Base64.encodeBytes(encrypted); StringBuffer strBuf = new StringBuffer(); strBuf.append(new String(encryptedStr)); strBuf.append("]"); strBuf.append(new String(salt)); strBuf.append("]"); strBuf.append(new String(iv)); return new String(Base64.encodeBytes(strBuf.toString().getBytes())); } public byte[] decrypt(String code, String pwd) throws Exception { if (code == null || code.length() == 0) throw new Exception("Empty string"); String[] fields = new String(Base64.decode(code)).split("]"); byte[] cipherBytes = Base64.decode(fields[0]); byte[] salt = fields[1].getBytes(); byte[] iv = fields[2].getBytes(); KeySpec keySpec = new PBEKeySpec(pwd.toCharArray(), salt, iterationCount, keyLength); SecretKeyFactory keyFactory = SecretKeyFactory .getInstance("PBKDF2WithHmacSHA1"); byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); SecretKey key = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivParams = new IvParameterSpec(iv); byte[] decrypted = null; cipher.init(Cipher.DECRYPT_MODE, key, ivParams); decrypted = cipher.doFinal(cipherBytes); return decrypted; } }
- Cifrado en Android usando el algoritmo RSA con módulo dado y exponente
- Cómo puedo reproducir video desde byte en android
- Obtener "EVP_DecryptFinal_ex: longitud de bloque final errónea" durante el desencriptado
- Uso de Android NDK para el cifrado de datos pasados de la aplicación normal de Android
- Cifrado AES Java -> PHP -> Java
- ¿Cómo utilizo una clave pública RSA generada en C # en Android?
- Problema al usar la huella dactilar de Android: IV necesaria al descifrar. Utilice IvParameterSpec o AlgorithmParameters para proporcionarlo
- Ocultar clave de cifrado en la aplicación de Android
Mira este
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import android.util.Base64; import android.util.Log; public class AesFileIo { // private static final String AES_ALGORITHM = "AES/CTR/NoPadding"; private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding"; private SecretKeySpec secretKeySpec; private IvParameterSpec ivSpec; public AesFileIo(byte[] aesKey, byte[] iv) { ivSpec = new IvParameterSpec(iv); secretKeySpec = new SecretKeySpec(aesKey, "AES"); } public String decrypt(String text) { StringBuilder stringBuilder = new StringBuilder(); try { Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec); byte[] decordedValue = Base64.decode(text,Base64.DEFAULT); String decryptedValue = new String(cipher.doFinal(decordedValue),"UTF-8"); Log.e("decrypted Value :",decryptedValue); return decryptedValue; } catch (Exception e) { Log.e(this.getClass().toString(), e.getMessage(), e); } return stringBuilder.toString(); } public String encrypt(String text) { String encryptedValue=null; try { Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec); byte[] encValue = cipher.doFinal(text.getBytes()); encryptedValue = Base64.encodeToString(encValue,Base64.DEFAULT); } catch (Exception e) { Log.e(this.getClass().toString(), e.getMessage(), e); } return encryptedValue; } }
Cómo utilizar
public static byte[] iv = { '0', '0','0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' }; private static final byte[] keyValue = new byte[] { 'b', 'i', 'r', 'a', 'j', 'z', 'a', 'l', 'a', 'v', 'a', 'd', 'i', 'y', 'a', 'r' }; AesFileIo aes = new AesFileIo(keyValue, iv); String encrypetedText = aes.encrypt(str); String decryptedText = aes.decrypt(encrypetedText); System.out.println("EncrypetedText : " + encrypetedText); System.out.println("DecryptedText : " + decryptedText);
- ¿Cómo obtener información sobre la versión de una biblioteca incluida?
- ¿Cómo puedo configurar ProxySettings y ProxyProperties en la conexión Wi-Fi de Android usando Java?