AES: last block incomplete in decryption
Résolu
moi411
Messages postés
45
Date d'inscription
Statut
Membre
Dernière intervention
-
moi411 Messages postés 45 Date d'inscription Statut Membre Dernière intervention -
moi411 Messages postés 45 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'aimerais tester le cryptage/décryptage AES sur un appareil android.
J'ai fait des recherches et j'ai trouvé une solution pour crypter.
Le décryptage, me renvoie une exception: last block incomplete in decryption.
Les fonctions:
dernière information: Si j'utilise le cryptage et le décryptage dans la même fonction, sans aucune action entre les deux, je n'ai aucun problème (mais niveau utilité c'est 0!!!)
Je m'explique:
Merci à ceux qui auront une idée!
A bientôt.
--
J'aimerais tester le cryptage/décryptage AES sur un appareil android.
J'ai fait des recherches et j'ai trouvé une solution pour crypter.
Le décryptage, me renvoie une exception: last block incomplete in decryption.
Les fonctions:
//crypter
public byte[] encrypt(byte[] raw, byte[] clear) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
//décypter
public byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception
{
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
//utiliser le cryptage dans l'application.
public String AES(String text, boolean crypter) //si true, on crypte sinon on décrypte
{
String finalCrypt = null;
byte[] encryptedData = null;
byte[] decryptedData = null;
try
{
byte[] b = text.getBytes();
byte[] keyStart = (editTextPassword.getText().toString()).getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
if(crypter == true)
{
encryptedData = aes.encrypt(key, b);
finalCrypt = Base64.encodeToString(encryptedData,Base64.NO_WRAP);
}
else
{
decryptedData = aes.decrypt(key, b);
finalCrypt = new String(decryptedData);
}
}
catch(Exception e)
{
messageBoxPerso("exception\n\n" + e.getMessage());
//la fameuse exception!
}
return finalCrypt;
}
dernière information: Si j'utilise le cryptage et le décryptage dans la même fonction, sans aucune action entre les deux, je n'ai aucun problème (mais niveau utilité c'est 0!!!)
Je m'explique:
try
{
AESCrypt aes = new AESCrypt();
String test = "My text.";
byte[] b = test.getBytes();
byte[] keyStart = "Une clef au hasard".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
// encrypt
byte[] encryptedData = aes.encrypt(key, b);
// decrypt
byte[] decryptedData = aes.decrypt(key, encryptedData);
//le cryptage et le décryptage sont fait à la suite
messageBoxPerso("Crypt: " + Base64.encodeToString(encryptedData,Base64.NO_WRAP) + "\nDecrypt: " + new String(decryptedData));
}
catch(Exception e)
{
messageBoxPerso("exception: " + e.getMessage());
}
Merci à ceux qui auront une idée!
A bientôt.
--
7 réponses
-
Hello,
Est-ce que ceci peut t'aider?
https://stackoverflow.com/questions/13261252/javax-crypto-illegalblocksizeexception-last-block-incomplete-in-decryption-de
-
Hello,
As-tu testé la validité de tes chaines en entrée de la decryption par exemple? N'y a-t-il pas des caractères farfelus?
-
Re,
Alors effectivement j'ai des caractères un peu bizarre que j'arrive à "voir" grâce à java.util.Arrays.toString(a.getBytes()). Apparemment se sont des espaces mais j'arrive à les supprimer en utilisant le paramètre "Base64.NO_WRAP" lors du cryptage...
En dehors de ça je ne vois rien de spécial!
Voilà je te remercie!
-- -
Des espaces à l'intérieur de la chaine? Bizarre...
Si c'est des espaces aux extrémités, tu peux utiliser la fonction trim() de String.
-
Re,
Alors effectivement je n'avais pas pensé à la fonction trim (honte à moi!)...
Sinon le cryptage et le décryptage fonctionnent si je n'enregistre pas les chaines (dans un fichier par exemple).
Par contre si je crypte un mot et que j'enregistre ce cryptage dans un fichier, lors du décryptage j'obtiens l'exception: last block incomplete in decryption!
pour enregistrer:
public void fichierAjouter(String valeur)
{
valeur = valeur + System.getProperty("line.separator");
try
{
FileWriter writer = new FileWriter("fichier.txt", true);
writer.write(valeur, 0, valeur.length());
writer.close();
}
catch(IOException exc)
{
messageBoxPerso("Problème avec le fichier!");
}
}
En attendant je te remercie ! Je pense que je n'ai rien oublié!
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Donc j'ai bien testé à plusieurs endroits de mes fonctions et mes chaines sont bien identiques à chaque fois... En revanche j'ai toujours la même erreur au même endroit...
Dans la fonction decrypt à la ligne:
byte[] decrypted = cipher.doFinal(encrypted);
A bientôt!
-- -
Bonjour,
Petite modification et évidemment nouvelle question. Juste une!!!
Tout d'abord le code:
//les variables utilisées pour lier l'activity au code private EditText editTextClef; //la clef de 32 caractères private EditText editTextPassword; //le mot à crypter private TextView textViewCrypte; //le résultat du cryptage private TextView textViewDecrypte; //le résultat du décryptage private Button buttonCrypter; //bouton pour crypter private Button buttonDecrypter; //bouton pour décrypter //utilisées pour le cryptage / decryptage private String password; //la clef private byte[] ivBytes; private static String salt; private int pswdIterations = 65536; private int keySize = 256; //une fonction pour remplir la variable salt public String genererSalt() { byte bytes[] = new byte[] { 0x01, 0x05, 0x07, 0x08, 0x08, 0x02, 0x04, 0x09 }; String s = new String(bytes); return s; } @override protected void onCreate etc.{... password = editTextClef.getText().toString(); //un bouton qui va crypter et afficher le résultat dans un textView buttonCrypter.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { //remplir salt salt = genererSalt(); byte[] saltBytes = salt.getBytes("iso-8859-1"); //derive the key SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); //encrypt the message Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); byte[] encryptedTextBytes = cipher.doFinal((editTextPassword.getText().toString()).getBytes("iso-8859-1")); textViewCrypte.setText(new String(encryptedTextBytes, Charset.forName("iso-8859-1"))); } catch(Exception e) { messageBoxPerso("Crypter:\n" + e.getMessage()); } } }); //un bouton qui va décrypter et afficher le résultat dans un textView buttonDecrypter.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { //get salt salt = genererSalt(); byte[] saltBytes = salt.getBytes("iso-8859-1"); byte[] encryptedTextBytes = (textViewCrypte.getText().toString()).getBytes("iso-8859-1"); //derive the key SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); //decrypt the message Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes); textViewDecrypte.setText(new String(decryptedTextBytes, Charset.forName("iso-8859-1"))); } catch(Exception e) { messageBoxPerso("Decrypter:\n" + e.getMessage()); } } });
Utilisée comme ça tout fonctionne correctement... Mais, sur tous les site où je suis allé, ils utilisent une classe, Base64, pour convertir en String...
Et toutes mes erreurs comme "last block incomplete in decryption" viennent de l'utilisation de cette classe!
D'ou ma question: Pourquoi?!?
-- -
Bonsoir,
Donc effectivement maintenant, ça marche...
Toujours pareil, c'est d'une logique imparable mais pas pensé!
Si on termine le cryptage par un encodage "Base64" alors on débute le décryptage par le décodage "Bas64".
Au cas où, je précise que sous android studio la classe Base64 est incluse.
La solution définitive:
//CRYPTAGE try { //get salt salt = generateSalt(); byte[] saltBytes = salt.getBytes("iso-8859-1"); //derive the key SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); //encrypt the message Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); byte[] encryptedTextBytes = cipher.doFinal((editTextPassword.getText().toString()).getBytes("iso-8859-1")); byte[] tmp = Base64.encode(encryptedTextBytes, Base64.NO_WRAP); textViewCrypte.setText(new String(tmp, Charset.forName("iso-8859-1"))); } catch(Exception e) { messageBoxPerso("Crypter:\n" + e.getMessage()); } //DECRYPTAGE try { //get salt salt = generateSalt(); byte[] saltBytes = salt.getBytes("iso-8859-1"); byte[] encryptedTextBytes = (textViewCrypte.getText().toString()).getBytes("iso-8859-1"); byte[] tmp = Base64.decode(encryptedTextBytes, Base64.NO_WRAP); //derive the key SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); //decrypt the message Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); byte[] decryptedTextBytes = cipher.doFinal(tmp); textViewDecrypte.setText(new String(decryptedTextBytes, Charset.forName("iso-8859-1"))); } catch(Exception e) { messageBoxPerso("Decrypter:\n" + e.getMessage()); }
Pour finir, je te remercie du coup de main!
Bonne soirée.
--