Мне нужно расшифровать файл в моем бэкэнде Laravel с помощью PHP openssl_decrypt.Файл зашифрован за пределами Laravel от ma BASH-скрипта и openssl 1.1.
Я посмотрел некоторые объяснения, которые могли бы помочь мне, но не нашел ничего, что работало.Мои версии openssl одинаковы (1.1) как для PHP, так и для сервера.Я перепробовал множество комбинаций опций, но ничего не получилось.
Вот мой сценарий шифрования BASH:
APP_KEY='**************'
FILES_PATH='****/app/files/'
# We're looking for ".decrypted" files, which gonna be encrypted next
FILES_LIST=$(find $FILES_PATH -type f -name '*.decrypted' )
# We base64-decode the key then display it as Hex. string
KEY=$(echo $APP_KEY | base64 -d -i | xxd -p -c 64)
# For each file to encrypt :
while read -r file; do
# If there is actually a file :
if [ ! -z "$file" ]; then
output=${file%.decrypted}
chunkspath="${output}.chunk."
chunksname="${chunkspath##*/}*"
# We have to split the files into 32M. chunks because our server can't decrypt big files without memory leaks in php.
split -b 32M -d $file -a 3 $chunkspath
chunkslist=$(find $FILES_PATH -type f -name $chunksname)
touch $output
# For each chunk :
while read -r chunk; do
# Generate a random IV of 16 bytes (output is 32 characters in Hex.)
iv=$(openssl rand -hex 16)
temp="${chunk}.enc"
openssl AES-256-CBC -K $KEY -iv $iv -in $chunk -out $temp
# We prefix each chunk with his IV to let the server retrieve it when decrypting. See the PHP code bellow.
echo -n $iv >> $output
# Then we append each IV+Chunk in the final output file.
cat $temp >> $output
rm $temp $chunk
done < <(echo "${chunkslist}")
# I commented the next line to let me run some tests but the original file will have to be removed eventually.
# rm $file
fi
done < <(echo "${FILES_LIST}")
echo 'Done'
А вот мой скрипт PHP для расшифровки файла:
// This function is inside a Laravel's stream download response
function () use ($file, $log) { // $file is the Laravel model representation of a stored file.
$cipher = 'AES-256-CBC';
$key = base64_decode(substr(config('app.key'), 7));
$ivLen = 32; // Actually 16 bytes but 32 characters in hex format
$chunckLen = 32 * 1024 * 1024; // Chunks are 32Mo long or less for the last one
$fpIn = fopen(Storage::disk('files')->path($file->path), 'rb');
while (!feof($fpIn)) {
// IV and Key must be in binary format
$iv = hex2bin(fread($fpIn, $ivLen));
// We read the file chunks by chunks, decrypt it and print it.
$encrypted = fread($fpIn, $chunckLen);
$decrypted = openssl_decrypt($encrypted, $cipher, $key, OPENSSL_RAW_DATA, $iv);
while ($msg = openssl_error_string()) {
print $msg . "\n";
}
print($decrypted);
}
}
Я ожидаю, что расшифрованный файл будет читаемым.С кодом выше, выходной файл содержит эту строку: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Я пытался с опциями OPENSSL_ZERO_PADDING для метода openssl_decrypt()
.Выходной файл затем содержит двоичные данные, но файл не читается (я думаю, что шифрование не сработало, как ожидалось).Я также попытался установить параметр -nopad в скрипте bash, но затем выдается эта ошибка: 4960:error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:data not multiple of block length:../openssl-1.1.1c/crypto/evp/evp_enc.c:425:
.Кто-то знает, что означают ошибки?Что я сделал не так ?Я почти уверен, что что-то пропустил (я новичок в мире шифрования ...)
Спасибо!