password library instalar extension example encrypt ejemplo crypto como cipher cbc java cryptography encryption

java - library - badPaddingException en alguna llamada del doFinal. No todo. La misma entrada



java encrypt cipher example (6)

Algunos pensamientos:

El seguimiento de la pila indica que el proveedor de BouncyCastle podría no ser recogido. Puede intentar pasar el proveedor de forma explícita a Cipher y KeyFactory.

El código que proporcionó es el único código que se está ejecutando, ¿no? No hay otros hilos en el proceso?

Me pregunto si podría confundir el cifrado especificando salt y iterationCount tanto en KeySpec como en ParameterSpec. Los ejemplos que veo ( cifran PBEWithMD5AndDES en j2me , http://cs.saddleback.edu/rwatkins/CS4B/Crypto/FileEncryptor.html ) no los especifica al crear KeySpec.

Uso un javax.crypto.cipher para cifrar y descifrar algunos datos. Está funcionando bien. Pero a veces, el descifrado falla con una badPaddingException. Si comparo una llamada satisfactoria con una llamada fallida, la entrada dada al cifrado es la misma, y ​​el cifrado se inicializa de la misma manera.

esa forma de instanciar mi cifrado

dcipher = Cipher.getInstance("PBEWithMD5AndDES"); KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount); SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

Así como lo uso

dec = Base64.decode(str) ; byte[] utf8 = dcipher.doFinal(dec);

La excepción se plantea en el doFinal.

Alguna idea ?

Gracias !

Oh, por cierto, uso BouncyCastle como proveedor, y lo agrego en la parte superior de la lista con

Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1);

Por el bien de la integridad, y porque el problema todavía aparece de vez en cuando. Aquí está la clase completa.

public class EncryptDecryptUtil { /** Encryption Cipher */ private static Cipher ecipher; /** Decription Cipher */ private static Cipher dcipher; private static Logger logger = Logger.getLogger(EncryptDecryptUtil.class); /** * Constructor used to create this object. Responsible for setting and initializing this object''s encrypter and * decrypter Cipher instances given a Secret Key and algorithm. * * @param key Secret Key used to initialize both the encrypter and decrypter instances. * @param algorithm Which algorithm to use for creating the encrypter and decrypter instances. */ public EncryptDecryptUtil(SecretKey key, String algorithm) { Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1); try { ecipher = Cipher.getInstance(algorithm); dcipher = Cipher.getInstance(algorithm); ecipher.init(Cipher.ENCRYPT_MODE, key); dcipher.init(Cipher.DECRYPT_MODE, key); } catch (NoSuchPaddingException e) { System.out.println("EXCEPTION: NoSuchPaddingException"); } catch (NoSuchAlgorithmException e) { System.out.println("EXCEPTION: NoSuchAlgorithmException"); } catch (InvalidKeyException e) { System.out.println("EXCEPTION: InvalidKeyException"); } } /** * Constructor used to create this object. Responsible for setting and initializing this object''s encrypter and * decrypter Chipher instances given a Pass Phrase and algorithm. * * @param passPhrase Pass Phrase used to initialize both the encrypter and decrypter instances. */ public EncryptDecryptUtil(String passPhrase) { Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1); // 8-bytes Salt byte[] salt = { (byte) 0xB9, (byte) 0x8B, (byte) 0xD8, (byte) 0x31, (byte) 0x55, (byte) 0x24, (byte) 0xF3, (byte) 0x13 }; // Iteration count int iterationCount = 19; try { // Generate the secret key associated to the passphrase. KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount); SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec); // Get instance of the cipher ecipher = Cipher.getInstance("PBEWithMD5AndDES"); dcipher = Cipher.getInstance("PBEWithMD5AndDES"); // Prepare the parameters to the cipthers AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount); ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec); } catch (InvalidAlgorithmParameterException e) { logger.error("during encrypter instantiation",e); } catch (InvalidKeySpecException e) { logger.error("during encrypter instantiation",e); } catch (NoSuchPaddingException e) { logger.error("during encrypter instantiation",e); } catch (NoSuchAlgorithmException e) { logger.error("during encrypter instantiation",e); } catch (InvalidKeyException e) { logger.error("during encrypter instantiation",e); } } /** * Takes a single String as an argument and returns an Encrypted version of that String. * * @param str String to be encrypted * @return <code>String</code> Encrypted version of the provided String */ public String encrypt(String str) { try { // Encode the string into bytes using utf-8 byte[] utf8 = str.getBytes("UTF8"); // Encrypt byte[] enc = ecipher.doFinal(utf8); // Encode bytes to base64 to get a string return new String( Base64.encode(enc), "UTF8"); } catch (BadPaddingException e) { logger.error("during encryption : ",e); } catch (IllegalBlockSizeException e) { logger.error("during encryption : ",e); } catch (UnsupportedEncodingException e) { logger.error("during encryption : ",e); } return new String(); } /** * Takes a encrypted String as an argument, decrypts and returns the decrypted String. * * @param str Encrypted String to be decrypted * @return <code>String</code> Decrypted version of the provided String */ public String decrypt(String str) { byte[] dec = new byte[0]; try { // Decode base64 to get bytes. Not sure to understand why. dec = Base64.decode(str) ; // Decrypt byte[] utf8 = dcipher.doFinal(dec); // Decode using utf-8 return new String(utf8, "UTF8"); } catch (BadPaddingException e) { logger.error("error during decryption. String to decode was : "+str + " byte array to decode was : "+ Arrays.toString(dec) ,e); } catch (IllegalBlockSizeException e) { logger.error("during decryption : ",e); } catch (UnsupportedEncodingException e) { logger.error("during decryption : ",e); } return new String(); } }

Editar: Me gustaría hacer hincapié en estos 2 puntos:

  • la misma entrada fallará alguna vez / a veces se descifrará con éxito. (Lo sé gracias a los registros en BadPaddingException)
  • esta llamada principal al método de descifrado 1 000 000 000 de veces reproduce el issus.

...

for( int i = 0 ; i<1000000000 ; i++){ EncryptDecryptUtil encryptDecript = new EncryptDecryptUtil("pass"); if ( !"YES".equals(encryptDecript.decrypt("Q3qWLKo6yJY="))){ System.out.println("Fail at call " + i); throw new InvalidParameterException() ; } }

Entonces, ¿podría venir de la forma en que uso la clase EncryptDecryptUtils? Es un campo de un frijol de primavera, se instaló una vez.

com.myStuff.dlm.cryptography.EncryptDecryptUtil error during decryption. String to decode was : Q3qWLKo6yJY= byte array to decode was : [114, 52, -52, -54, 82, 87, 124, 84] javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.SunJCE_ab.b(DashoA13*..) at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineDoFinal(DashoA13*..) at javax.crypto.Cipher.doFinal(DashoA13*..) at com.dvidea.dlm.cryptography.EncryptDecryptUtil.decrypt(EncryptDecryptUtil.java:166)


Es un poco oscuro, pero intenta crear una instancia de tu cifrado de esta manera:

dcipher = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");



Solo una idea: tal vez estés saltando entre diferentes proveedores (Sun / BC / etc)

Saludos.


Voy a dar un paso en falso y sugerir que es un tema de seguridad de subprocesos. Intente agregar bloques synchronized alrededor de las ecipher/dcipher#doFinal , puede usar fácilmente el objeto Cipher asociado como un objeto para sincronizar.

byte[] enc; synchronized (ecipher) { enc = ecipher.doFinal(utf8); }


badPaddingException generalmente significa que la contraseña fue incorrecta. Usando "contraseña incorrecta" como la contraseña recrea el error:

EncryptDecryptUtil encryptDecript = new EncryptDecryptUtil("wrong_password"); encryptDecript.decrypt("Q3qWLKo6yJY=");

Resultados:

error during decryption. String to decode was : Q3qWLKo6yJY= byte array to decode was : [67, 122, -106, 44, -86, 58, -56, 106] javax.crypto.BadPaddingException: Given final block not properly padded