Rembourrage Exception: compte tenu de bloc final pas correctement rembourré
Je suis en train de chiffrer et de déchiffrer mon fichier dans lequel tous mes mots de passe sont stockés à l'aide de l'algorithme AES.
L'algorithme fonctionne très bien sur le chiffrage de la partie. Mais tandis que le déchiffrement, il jette l'erreur
Message:Given final block not properly padded
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2121)
at SearchDoc.dec_file(SearchDoc.java:327)
at SearchDoc.access$100(SearchDoc.java:52)
at SearchDoc$2$1.actionPerformed(SearchDoc.java:227)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Quel est le problème ici?
code:
//Starting decryption
try{
byte[] key = c_key.getBytes("ISO-8859-1");
key = Arrays.copyOf(key, 16); //use only first 128 bit
//System.out.println(Arrays.toString(key));
SecretKeySpec SecKey = new SecretKeySpec(key, "AES");
Cipher AesCipher = Cipher.getInstance("AES");
AesCipher.init(Cipher.DECRYPT_MODE, SecKey);
BufferedReader breader = new BufferedReader(new FileReader("download/enc_"+file));
String line;
boolean bool = false;
File f = new File(file);
bool = f.createNewFile();
if(bool==false){
f.delete();
bool = f.createNewFile();
}
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
while ((line = breader.readLine()) != null){
byte[] cipher=null;
byte[] plain=null;
cipher=line.getBytes("ISO-8859-1");
plain=AesCipher.doFinal(cipher);
out.println(new String(plain,"ISO-8859-1"));
}
out.close();
return 1;
}
catch(Exception dcf){
System.out.println("Message:"+dcf.getMessage());
dcf.printStackTrace();
return 0;
}
NOUVEAU AES CODE:
import java.security.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import sun.misc.*;
public class AESencrp {
private static final String ALGO = "AES";
private static final byte[] keyValue =
new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
}
Vous devez vous connecter pour publier un commentaire.
En utilisant simplement
AES
que de chiffrement par exemple, n'a pas expliqué comment le dernier bloc est rembourré. C'est pourquoi le chiffrement et le déchiffrement peuvent différer.Utilisez l'une des méthodes suivantes, en béton de chiffrement des instances de la place (en fonction de votre mode de cryptage):
Vous pouvez trouver une liste des algorithmes de chiffrement ici
Input length must be multiple of 16 when decrypting with padded cipher
decrypt(encrypt("secrect") + "bar)"
). Remarque: Le code que vous avez posté utiliseAES/ECB/PKCS5Padding
(Java par défaut), qui ne devrait être utilisé lors du chiffrement d'un seul bloc. Voir: stackoverflow.com/questions/1220751/...`En supposant que vous avez chiffré le en texte brut d'origine linewise, vous ne serez pas capable de le décrypter linewise. Texte chiffré peut contenir des tout octet de valeur, y compris ceux pour
\n
. Donc, si vous avez chiffré chaque ligne de texte en clair dans une autre invocation, vous obtenez parfois une cryptogramme "ligne" qui a un octet qui correspond à\n
. Si maintenant vous souhaitez décrypter ce, il ne sera pas possible, parce que les frontières entre ces Cipher invocations sont différents.Pour résoudre ce problème, vous devez soit de chiffrer l'ensemble du document dans une invocation (utiliser
CipherInputStream
/CipherOutputStream
si vous avez des problèmes de mémoire) ou crypter chaque ligne séparément, mais assurez-vous de connaître les limites dans le texte chiffré.La dernière approche peut être fait par exemple par l'encodage de chaque partie du texte chiffré de telle manière que
\n
n'est pas présent dans celui-ci. Vous pouvez, par exemple, coder en Base 64, mais qui blowup votre texte chiffré à environ 33%.Je vous suggère d'utiliser l'ancienne méthode avec un seul appel.
Que flo mentionné, il est toujours préférable d'utiliser pleinement qualifié de Chiffrement des chaînes, parce que les différentes versions de Java peuvent utiliser différents par défaut pour le mode de fonctionnement ou de rembourrage et vous pouvez vous retrouver avec irrécupérable texte chiffré.