AES: last block incomplete in decryption
Résolu
moi411
Messages postés
183
Statut
Membre
-
moi411 Messages postés 183 Statut Membre -
moi411 Messages postés 183 Statut Membre -
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.
--
A voir également:
- Javax.crypto.illegalblocksizeexception: last block incomplete in decryption
- Rapport de stage aes exemple - Guide
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
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?
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!
--
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.
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:
En attendant je te remercie ! Je pense que je n'ai rien oublié!
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!
--
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:
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?!?
--
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:
Pour finir, je te remercie du coup de main!
Bonne soirée.
--
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.
--