Cipher doFinal tampon de bloc endommagé lors du déchiffrement du fichier avec l'algorithme AES
Je suis entrain de créer un programme qui permet aux utilisateurs de charger et télécharger des fichiers chiffrés et les décrypter si ils ont les autorisations appropriées pour le faire. Le chiffrement et le téléchargement est très bien, et donc est en cours de téléchargement, mais quand j'ai essayer de déchiffrer-je obtenir le "bloc de pavé corrompu" erreur.
Ce que je suis en train de faire est de prendre le fichier crypté et ensuite faire une copie qui n'est pas crypté
J'ai raccourci de ce que je pouvais donc merci de ne pas remarquer qu'elle semble incomplète.
KeyGen:
public static SecretKey genGroupSecretKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC");
keyGen.init(128);
return keyGen.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace(System.err);
}
return null;
}
Chiffrer:
try (FileInputStream fis = new FileInputStream(sourceFile)) {
response = Utils.decryptEnv((byte[]) tempResponse.getObjContents().get(0), fsSecretKey, ivSpec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
do {
byte[] buf = new byte[4096];
int n = fis.read(buf); //can throw an IOException
else if (n < 0) {
System.out.println("Read error");
fis.close();
return false;
}
byte[] cipherBuf = cipher.doFinal(buf);
//send through socket blah blah blah
} while (fis.available() > 0);
Déchiffrer:
...
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, secKey, ivSpec);
File file = new File("D_" + filename); //D_ for decrypted
FileOutputStream fos = null;
if (!file.exists()) {
file.createNewFile();
fos = new FileOutputStream(file);
}
try (FileInputStream fis = new FileInputStream(filename)) {
do {
byte[] buf = new byte[4096];
int n = fis.read(buf);
if (n < 0) {
System.out.println("Read error");
fis.close();
return false;
}
byte[] cipherBuf = cipher.doFinal(buf); //ERROR HERE
System.out.println("IS THIS WORKING WTF: " + new String(cipherBuf));
fos.write(cipherBuf, 0, n);
} while (fis.available() > 0);
fis.close();
fos.close();
return true;
Vous devez vous connecter pour publier un commentaire.
Vous devriez vous
Cipher.doFinal()
uniquement pour le dernier bloc de données. Vous devez modifier à la fois de cryptage et de décryptage de code pour utiliserCipher.update()
pour tous les intermédiaires de données et l'utilisation d'un seul appel àCipher.doFinal()
à la fin. Il est permis d'utiliserCipher.update()
pour tous les intermédiaires de bloc de données, et il suffit d'appeler leCipher.doFinal()
avec le tableau vide à la fin.Aussi, vous êtes ignorant la valeur de retour de
fis.read(buf)
lorsque vous transmettez les données lues à partir du flux de l'algorithme de chiffrement.Aussi, vous êtes à l'aide de
InputStream.available()
comme une condition à la fin du cycle. Même si le code à l'intérieur du cycle serait correct, vous obtiendrez des résultats imprévisibles en raison de fausses déclenchement du cycle de condition.Utiliser le modèle suivant pour travailler avec les algorithmes de chiffrement:
Vérifier d'autres variantes de
Cipher.update()
- il est possible d'utiliser deux pré-allouée tampons et de minimiser les allocations supplémentaires.Également vérifier si vous pouvez réutiliser
javax.crypto.CipherInputStream
etjavax.crypto.CipherOutputStream
classes de sorte que vous n'avez pas à travailler avec le chiffrement directement.InputStream.read(byte[])
que vous devez utiliser lorsque vous transmettez les données de la classe suivante.Si l'objectif est juste pour crypter et décrypter un fichier, le programme suivant peut aider.