Issue
I want to encrypt and decrypt a gzip file with openssl. When I am trying to decrypt my encrypt file I have this openssl error : error:1c800064:provider routines::bad decrypt. I verified that the keys and IVs are the same with bool variable of php as you will can see in my code (Merge try). If someone could help me.
Setup :
- Ubuntu 22.04.3 LTS
- PHP 8.1.22 (cli)
- Openssl 3.0.2
Encrypt part :
$key = $db->fetch_object($resql);
print $key->pass_crypted . "\n";
$key->pass_crypted = substr($key->pass_crypted, 0, 32);
print $key->pass_crypted . "\n";
if ($key === false) {
die("Aucune clé n'a été trouvée dans la base de données.");
}
$outputFilePath = $outputdir . "/c" . $file . ".gz";
// Vérification si le fichier source existe
$sourceFilePath = $outputdir . "/" . $file . ".gz";
if (!file_exists($sourceFilePath)) {
die("Le fichier source n'existe pas : " . $sourceFilePath);
}
// Vecteur d'initialisation (IV) (128 bits, 16 octets)
$iv = openssl_random_pseudo_bytes(16);
print $iv . "\n";
// Solution par morceau
// Ouvrir le fichier source en lecture
$sourceFile = fopen($sourceFilePath, 'r');
if (!$sourceFile) {
die("Impossible d'ouvrir le fichier source : $sourceFilePath");
}
// Ouvrir le fichier de sortie en écriture
$outputFile = fopen($outputFilePath, 'w');
if (!$outputFile) {
die("Impossible d'ouvrir le fichier de sortie : $outputFilePath");
}
if (fwrite($outputFile, $iv) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
// Définir la taille du morceau (en octets)
$chunkSize = 1024; // 1 Mo
while (!feof($sourceFile)) {
// Lire un morceau du fichier source
$chunk = fread($sourceFile, $chunkSize);
if ($chunk === false) {
die("Erreur lors de la lecture du fichier source.");
}
// Chiffrer le morceau
$encryptedChunk = openssl_encrypt($chunk, 'aes-256-cbc', $key->pass_crypted, OPENSSL_RAW_DATA, $iv);
if ($encryptedChunk === false) {
die("Erreur lors du chiffrement du morceau.");
}
// Écrire le morceau chiffré dans le fichier de sortie
if (fwrite($outputFile, $encryptedChunk) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
}
// Fermer les fichiers
fclose($sourceFile);
fclose($outputFile);
echo "Le fichier a été chiffré avec succès.\n";
// Supprimer le fichier source
if (!unlink($sourceFilePath)) {
die("Erreur lors de la suppression du fichier source.");
}
Decrypt part :
<?php
$key = 'key'; //Modifiable
$inputFilePath = "/var/www/html/dolibarr/doc/admin/documents/cdocuments_dolibarr-lm_17.0.3_20230918122547.tar.gz"; //Modifiable
$decryptedFilePath = "cdocuments_dolibarr-lm_17.0.3_20230918103956.tar.gz"; //Modifiable
// Vérification si le fichier chiffré existe
if (!file_exists($inputFilePath)) {
die("Le fichier chiffré n'existe pas : " . $inputFilePath);
}
// Ouvrir le fichier chiffré
if (! $encryptedFile = fopen($inputFilePath, "r")) {
die("Erreur lors de l'ouverture du fichier chiffré.");
}
//Ouvrir le fichier déchiffré
if (! $decryptedFile = fopen($decryptedFilePath, "w")) {
die("Erreur lors de l'ouverture du fichier déchiffré.");
}
$chunkSize = 1024;
// Récupération de l'IV (16 premiers octets)
if (! $iv = fread($encryptedFile, 16)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
print $iv . "\n";
// Ecriture du fichier déchiffré
while (!feof($encryptedFile)) {
if (! $encryptedData = fread($encryptedFile, $chunkSize)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
$decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
if ($decryptedData === false) {
print openssl_error_string();
die("Erreur lors du déchiffrement.");
}
if (! fwrite($decryptedFile, $decryptedData)) {
die("Erreur lors de l'écriture du fichier déchiffré.");
}
}
echo "Le fichier a été déchiffré avec succès dans : " . $decryptedFilePath . "\n";
?>
Merge try :
$key = $db->fetch_object($resql);
print $key->pass_crypted . "\n";
$key->pass_crypted = substr($key->pass_crypted, 0, 32);
print $key->pass_crypted . "\n";
if ($key === false) {
die("Aucune clé n'a été trouvée dans la base de données.");
}
$outputFilePath = $outputdir . "/c" . $file . ".gz";
// Vérification si le fichier source existe
$sourceFilePath = $outputdir . "/" . $file . ".gz";
if (!file_exists($sourceFilePath)) {
die("Le fichier source n'existe pas : " . $sourceFilePath);
}
// Vecteur d'initialisation (IV) (128 bits, 16 octets)
$iv = openssl_random_pseudo_bytes(16);
print $iv . "\n";
// Solution par morceau
// Ouvrir le fichier source en lecture
$sourceFile = fopen($sourceFilePath, 'r');
if (!$sourceFile) {
die("Impossible d'ouvrir le fichier source : $sourceFilePath");
}
// Ouvrir le fichier de sortie en écriture
$outputFile = fopen($outputFilePath, 'w');
if (!$outputFile) {
die("Impossible d'ouvrir le fichier de sortie : $outputFilePath");
}
if (fwrite($outputFile, $iv) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
// Définir la taille du morceau (en octets)
$chunkSize = 1024; // 1 Mo
while (!feof($sourceFile)) {
// Lire un morceau du fichier source
$chunk = fread($sourceFile, $chunkSize);
if ($chunk === false) {
die("Erreur lors de la lecture du fichier source.");
}
// Chiffrer le morceau
$encryptedChunk = openssl_encrypt($chunk, 'aes-256-cbc', $key->pass_crypted, OPENSSL_RAW_DATA, $iv);
if ($encryptedChunk === false) {
die("Erreur lors du chiffrement du morceau.");
}
// Écrire le morceau chiffré dans le fichier de sortie
if (fwrite($outputFile, $encryptedChunk) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
}
// Fermer les fichiers
fclose($sourceFile);
fclose($outputFile);
echo "Le fichier a été chiffré avec succès.\n";
// Supprimer le fichier source
if (!unlink($sourceFilePath)) {
die("Erreur lors de la suppression du fichier source.");
}
/*
* Fin Chiffrement de l'archive (symétrique)
*/
$key2 = $key->pass_crypted; //Modifiable
print "flag_key : ";
$flag_key = $key->pass_crypted == $key2;
var_dump($flag_key);
print "\n";
$inputFilePath = $outputFilePath; //Modifiable
$decryptedFilePath = $outputdir . "/" . $file . ".gz"; //Modifiable
// Vérification si le fichier chiffré existe
if (!file_exists($inputFilePath)) {
die("Le fichier chiffré n'existe pas : " . $inputFilePath);
}
// Ouvrir le fichier chiffré
if (! $encryptedFile = fopen($inputFilePath, "r")) {
die("Erreur lors de l'ouverture du fichier chiffré.");
}
//Ouvrir le fichier déchiffré
if (! $decryptedFile = fopen($decryptedFilePath, "w")) {
die("Erreur lors de l'ouverture du fichier déchiffré.");
}
$chunkSize = 1024;
// Récupération de l'IV (16 premiers octets)
if (! $iv2 = fread($encryptedFile, 16)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
print $iv2 . "\n";
print "flag_iv : ";
$flag_iv = $iv == $iv2;
var_dump($flag_iv);
print "\n";
// Ecriture du fichier déchiffré
while (!feof($encryptedFile)) {
if (! $encryptedData = fread($encryptedFile, $chunkSize)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
$decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key2, OPENSSL_RAW_DATA, $iv2);
print $key2 . "\n";
if ($decryptedData === false) {
print openssl_error_string();
die("Erreur lors du déchiffrement.\n");
}
if (! fwrite($decryptedFile, $decryptedData)) {
die("Erreur lors de l'écriture du fichier déchiffré.");
}
}
echo "Le fichier a été déchiffré avec succès dans : " . $decryptedFilePath . "\n";
I also tried to open files in binary mode, but without success. (My IVs were not the same)
Edit
@Sammitch so I tried to implement your proposal but I have the same error : error:1C800064:Provider routines::bad decrypt.
$resql = $db->query($sql);
if ($resql === false) {
die("Erreur lors de la requête SQL : " . $db->lasterror());
}
$key = $db->fetch_object($resql);
print $key->pass_crypted . "\n";
$key->pass_crypted = substr($key->pass_crypted, 0, 32);
print $key->pass_crypted . "\n";
if ($key === false) {
die("Aucune clé n'a été trouvée dans la base de données.");
}
$outputFilePath = $outputdir . "/c" . $file . ".gz";
// Vérification si le fichier source existe
$sourceFilePath = $outputdir . "/" . $file . ".gz";
if (!file_exists($sourceFilePath)) {
die("Le fichier source n'existe pas : " . $sourceFilePath);
}
// Solution par morceau
// Ouvrir le fichier source en lecture
$sourceFile = fopen($sourceFilePath, 'r');
if (!$sourceFile) {
die("Impossible d'ouvrir le fichier source : $sourceFilePath");
}
// Ouvrir le fichier de sortie en écriture
$outputFile = fopen($outputFilePath, 'w');
if (!$outputFile) {
die("Impossible d'ouvrir le fichier de sortie : $outputFilePath");
}
// Définir la taille du morceau (en octets)
$chunkSize = 1024; // 1 Mo
while (!feof($sourceFile)) {
// Vecteur d'initialisation (IV) (128 bits, 16 octets)
$iv = openssl_random_pseudo_bytes(16);
// Lire un morceau du fichier source
$chunk = fread($sourceFile, $chunkSize);
if ($chunk === false) {
die("Erreur lors de la lecture du fichier source.");
}
// Chiffrer le morceau
$encryptedChunk = openssl_encrypt($chunk, 'aes-256-cbc', $key->pass_crypted, OPENSSL_RAW_DATA, $iv);
if ($encryptedChunk === false) {
die("Erreur lors du chiffrement du morceau.");
}
// Écrire le morceau chiffré dans le fichier de sortie
if (fwrite($outputFile, $encryptedChunk) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
if (fwrite($outputFile, $iv) === false) {
die("Erreur lors de l'écriture du IV dans le fichier chiffré.");
}
}
// Fermer les fichiers
fclose($sourceFile);
fclose($outputFile);
echo "Le fichier a été chiffré avec succès.\n";
// Supprimer le fichier source
if (!unlink($sourceFilePath)) {
die("Erreur lors de la suppression du fichier source.");
}
/*
* Fin Chiffrement de l'archive (symétrique)
*/
$key2 = $key->pass_crypted; //Modifiable
print "flag_key : ";
$flag_key = $key->pass_crypted == $key2;
var_dump($flag_key);
print "\n";
$inputFilePath = $outputFilePath; //Modifiable
$decryptedFilePath = $outputdir . "/" . $file . ".gz"; //Modifiable
// Vérification si le fichier chiffré existe
if (!file_exists($inputFilePath)) {
die("Le fichier chiffré n'existe pas : " . $inputFilePath);
}
// Ouvrir le fichier chiffré
if (! $encryptedFile = fopen($inputFilePath, "r")) {
die("Erreur lors de l'ouverture du fichier chiffré.");
}
//Ouvrir le fichier déchiffré
if (! $decryptedFile = fopen($decryptedFilePath, "w")) {
die("Erreur lors de l'ouverture du fichier déchiffré.");
}
$chunkSize = 1024;
// Ecriture du fichier déchiffré
while (!feof($encryptedFile)) {
if (! $encryptedData = fread($encryptedFile, $chunkSize)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
// Récupération de l'IV (16 dernies octets du chunk)
if (! $iv2 = fread($encryptedFile, 16)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
$decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key2, OPENSSL_RAW_DATA, $iv2);
if ($decryptedData === false) {
print openssl_error_string();
die("Erreur lors du déchiffrement.\n");
}
if (! fwrite($decryptedFile, $decryptedData)) {
die("Erreur lors de l'écriture du fichier déchiffré.");
}
}
echo "Le fichier a été déchiffré avec succès dans : " . $decryptedFilePath . "\n";
Solution
@Topaco Thank you a lot. I post here the correct merge code with CBC logic.
$resql = $db->query($sql);
if ($resql === false) {
die("Erreur lors de la requête SQL : " . $db->lasterror());
}
$key = $db->fetch_object($resql);
print $key->pass_crypted . "\n";
$key->pass_crypted = substr($key->pass_crypted, 0, 32);
print $key->pass_crypted . "\n";
if ($key === false) {
die("Aucune clé n'a été trouvée dans la base de données.");
}
$outputFilePath = $outputdir . "/c" . $file . ".gz";
// Vérification si le fichier source existe
$sourceFilePath = $outputdir . "/" . $file . ".gz";
if (!file_exists($sourceFilePath)) {
die("Le fichier source n'existe pas : " . $sourceFilePath);
}
// Solution par morceau
// Ouvrir le fichier source en lecture
$sourceFile = fopen($sourceFilePath, 'r');
if (!$sourceFile) {
die("Impossible d'ouvrir le fichier source : $sourceFilePath");
}
// Ouvrir le fichier de sortie en écriture
$outputFile = fopen($outputFilePath, 'w');
if (!$outputFile) {
die("Impossible d'ouvrir le fichier de sortie : $outputFilePath");
}
// Définir la taille du morceau (en octets)
$chunkSize = 1024; // 1 Mo
$iv = '';
while (!feof($sourceFile)) {
// Vecteur d'initialisation (IV) (128 bits, 16 octets)
if ($iv === '') {
// Premier bloc, on génère un IV aléatoire
$iv = openssl_random_pseudo_bytes(16);
fwrite($outputFile, $iv);
} else if ($encryptedChunk) {
// Bloc suivant, on récupère les 16 derneiers bits du dernier bloc chiffré
$iv = substr($encryptedChunk, -16);
} else {
die("Erreur lors de la génération du vecteur d'initialisation.");
}
// Lire un morceau du fichier source
$chunk = fread($sourceFile, $chunkSize);
if ($chunk === false) {
die("Erreur lors de la lecture du fichier source.");
}
// Chiffrer le morceau
$encryptedChunk = openssl_encrypt($chunk, 'aes-256-cbc', $key->pass_crypted, OPENSSL_RAW_DATA, $iv);
if ($encryptedChunk === false) {
die("Erreur lors du chiffrement du morceau.");
}
// Écrire le morceau chiffré dans le fichier de sortie
if (fwrite($outputFile, $encryptedChunk) === false) {
die("Erreur lors de l'écriture du fichier chiffré.");
}
}
// Fermer les fichiers
fclose($sourceFile);
fclose($outputFile);
echo "Le fichier a été chiffré avec succès.\n";
// Supprimer le fichier source
if (!unlink($sourceFilePath)) {
die("Erreur lors de la suppression du fichier source.");
}
/*
* Fin Chiffrement de l'archive (symétrique)
*/
$key2 = $key->pass_crypted; //Modifiable
print "flag_key : ";
$flag_key = $key->pass_crypted == $key2;
var_dump($flag_key);
print "\n";
$inputFilePath = $outputFilePath; //Modifiable
$decryptedFilePath = $outputdir . "/" . $file . ".gz"; //Modifiable
// Vérification si le fichier chiffré existe
if (!file_exists($inputFilePath)) {
die("Le fichier chiffré n'existe pas : " . $inputFilePath);
}
// Ouvrir le fichier chiffré
if (! $encryptedFile = fopen($inputFilePath, "r")) {
die("Erreur lors de l'ouverture du fichier chiffré.");
}
//Ouvrir le fichier déchiffré
if (! $decryptedFile = fopen($decryptedFilePath, "w")) {
die("Erreur lors de l'ouverture du fichier déchiffré.");
}
$chunkSize = 1024 + 16;
$iv2 = '';
// Ecriture du fichier déchiffré
while (!feof($encryptedFile)) {
// Récupération de l'IV (16 dernies octets du chunk)
if ($iv2 == '') {
// Pour le premier bloc on récupère les 16 premiers octets du fichier
$iv2 = fread($encryptedFile, 16);
} else if ($encryptedData) {
// Pour les blocs suivants on récupère les 16 derniers octets du bloc précédent
$iv2 = substr($encryptedData, -16);
} else {
die("Erreur lors de la génération du vecteur d'initialisation.");
}
if (! $encryptedData = fread($encryptedFile, $chunkSize)) {
die("Erreur lors de la lecture du fichier chiffré.");
}
$decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key2, OPENSSL_RAW_DATA, $iv2);
if ($decryptedData === false) {
print openssl_error_string();
die("Erreur lors du déchiffrement.\n");
}
if (! fwrite($decryptedFile, $decryptedData)) {
die("Erreur lors de l'écriture du fichier déchiffré.");
}
}
echo "Le fichier a été déchiffré avec succès dans : " . $decryptedFilePath . "\n";
Answered By - Skeuly Answer Checked By - Mary Flores (WPSolving Volunteer)