我想从上传文件中解密扩展名为 .txt .docx .xlsx 和 .pdf 的文件。
加密.php
<?php
include "koneksi.php";
function generateKeyPairFromFileName(){
$config = array(
"default_md" => "sha512",
"private_key_bits" => 512,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$keypair = openssl_pkey_new($config);
if (!$keypair) {
die("Failed to generate key pair");
}
openssl_pkey_export($keypair, $privateKey, null, $config);
$publicKey = openssl_pkey_get_details($keypair);
$publicKey = $publicKey['key'];
return array(
'publicKey' => $publicKey,
'privateKey' => $privateKey
);
}
function savePublicKeyToLocal($publicKey, $fileName) {
$publicKeyPath = $fileName . '_public_key.pem'; // Ganti dengan lokasi penyimpanan kunci publik Anda
file_put_contents($publicKeyPath, $publicKey);
return $publicKeyPath;
}
// Fungsi untuk menyimpan kunci pribadi ke file lokal
function savePrivateKeyToLocal($privateKey, $fileName) {
$privateKeyPath = $fileName . '_private_key.pem'; // Ganti dengan lokasi penyimpanan kunci pribadi Anda
file_put_contents($privateKeyPath, $privateKey);
return $privateKeyPath;
}
// Fungsi untuk mengenkripsi file menggunakan AES
function encryptFile($data, $key) {
// Buat vektor inisialisasi (IV) acak
$iv = openssl_random_pseudo_bytes(16);
// Enkripsi data menggunakan AES-256-CBC dengan kunci dan IV yang diberikan
$encryptedData = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
// Base64 encode hasil enkripsi
$encryptedDataBase64 = base64_encode($encryptedData);
// Simpan atau kirim data terenkripsi ke tempat penyimpanan atau penerima
// echo "Data terenkripsi: " . $encryptedDataBase64;
return $encryptedDataBase64;
}
if(isset($_POST['generate'])){
$uploadedFileName = $_FILES['file']['name'];
$filetmp = $_FILES['file']['tmp_name'];
// Membaca isi file
$fileContent = file_get_contents($filetmp);
$KeyPair = generateKeyPairFromFileName();
$publicKeyPath = savePublicKeyToLocal($KeyPair['publicKey'], $uploadedFileName);
$publicKeyPath = savePrivateKeyToLocal($KeyPair['privateKey'], $uploadedFileName);
$encryptedFileContent = encryptFile($fileContent, $KeyPair['publicKey']);
// echo $encryptedFileContent;
$query = "INSERT INTO upload (nama_file, filedata) VALUES ('$uploadedFileName', '$encryptedFileContent')";
if (mysqli_query($conn, $query)) {
echo "File berhasil diunggah dan dienkripsi.";
} else {
echo "Gagal mengunggah dan menyimpan file ke database: " . mysqli_error($conn);
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
Pilih file untuk diunggah (PDF, DOCX, XLSX, TXT, maks 15 MB):
<input type="file" name="file">
<button name="generate" type="submit">Generate</button>
</form>
我将私钥和公钥保存在本地。上面的脚本用于在保存到数据库之前加密数据。
ecnrypt.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include "koneksi.php";
// Fungsi dekripsi
function decryptFile($data, $key) {
// Decode data terenkripsi dari base64
$encryptedData = base64_decode($data);
// Ambil IV dari data terenkripsi
$iv = openssl_random_pseudo_bytes(16);
$decryptedData = openssl_decrypt($encryptedData, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
// Kembalikan data yang telah didekripsi
return $decryptedData;
}
if(isset($_GET['nama_file'])){
// Nama file
$fileName = $_GET['nama_file'];
// Membaca kunci privat
try {
$privateKeyPath = $fileName . '_private_key.pem';
if (!file_exists($privateKeyPath)) {
throw new Exception("File kunci privat tidak ditemukan: " . $privateKeyPath);
}
$privateKey = file_get_contents($privateKeyPath);
} catch (Exception $e) {
echo "Gagal membaca kunci privat: " . $e->getMessage();
exit;
}
// Mengambil data file terenkripsi dari database
$query = "SELECT filedata FROM upload WHERE nama_file = '$fileName'";
$result = mysqli_query($conn, $query);
if ($result && mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
// Dekripsi data
$decryptedData = decryptFile($row['filedata'], $privateKey);
// Tampilkan data yang telah didekripsi
echo $decryptedData;
} else {
echo "File tidak ditemukan!";
}
}
我要解密的文件是空的。我的意思是在解密的数据上返回空。有人有同样的问题吗?
期待包含解密数据的文件。
我检查了我的 PHP 脚本,它似乎有效地结合了 RSA 和 AES 加密来进行文件上传。
加密.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include "koneksi.php";
// Enkripsi
if(isset($_POST['generate'])){
// Mendapatkan informasi file yang diunggah
$uploadedFileName = $_FILES['file']['name'];
$uploadedFileSize = $_FILES['file']['size'];
$uploadedFileType = strtolower(pathinfo($uploadedFileName, PATHINFO_EXTENSION));
$sql = "SELECT nama_file FROM upload WHERE nama_file='$uploadedFileName'";
$query = mysqli_query($conn, $sql);
$rows = mysqli_num_rows($query);
if( $rows > 0) {
return header('location:./home.php?message=error');
}
// Batasi jenis file yang diperbolehkan dan ukuran file
$allowedTypes = array('txt', 'docx', 'pdf', 'xlsx');
$maxFileSize = 15 * 1024 * 1024; // 15 MB dalam bytes
if (in_array($uploadedFileType, $allowedTypes) && $uploadedFileSize <= $maxFileSize) {
// Menghasilkan pasangan kunci RSA
$rsaKey = openssl_pkey_new(array(
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA
));
// Mendapatkan kunci privat
openssl_pkey_export($rsaKey, $privateKey);
// Mendapatkan kunci publik
$publicKey = openssl_pkey_get_details($rsaKey)['key'];
// Menyimpan kunci dengan awalan nama file yang diunggah
$privateKeyFileName = pathinfo($uploadedFileName, PATHINFO_FILENAME) . "_private_key.pem";
$publicKeyFileName = pathinfo($uploadedFileName, PATHINFO_FILENAME) . "_public_key.pem";
// echo $privateKeyFileName;
file_put_contents('./keys/'. $privateKeyFileName, $privateKey);
file_put_contents('./keys/'. $publicKeyFileName, $publicKey);
// Menghasilkan kunci AES acak
$aesKey = openssl_random_pseudo_bytes(16);
// Mengenkripsi kunci AES menggunakan kunci publik RSA
openssl_public_encrypt($aesKey, $encAesKey, $publicKey);
// Unggah file
$uploadedFile = $_FILES['file']['tmp_name'];
// Mengenkripsi data menggunakan AES
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt(file_get_contents($uploadedFile), 'aes-128-cbc', $aesKey, 0, $iv);
// Menyimpan data terenkripsi ke sebuah variabel
$encryptedFileContent = $iv . $ciphertext;
// Menyimpan kunci AES terenkripsi ke sebuah file dengan awalan nama file yang diunggah
$encryptedAesKeyFileName = pathinfo($uploadedFileName, PATHINFO_FILENAME) . "_encrypted_aes_key.bin";
file_put_contents('./keys/'. $encryptedAesKeyFileName, $encAesKey);
// Memasukkan data file terenkripsi ke dalam database
$query = "INSERT INTO upload (nama_file, filedata, mimetype)
VALUES ('$uploadedFileName', '$encryptedFileContent', '$uploadedFileType')";
if (mysqli_query($conn, $query)) {
echo "File berhasil diunggah dan dienkripsi.";
header('location:./home.php?message=success');
} else {
echo "Gagal mengunggah dan menyimpan file ke database: " . mysqli_error($conn);
}
} else {
echo "Jenis file yang diunggah tidak diperbolehkan atau ukuran file melebihi batas maksimum.";
}
}
?>
解密.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include "koneksi.php";
if(isset($_GET['dekripsi'])) {
$id = $_GET['dekripsi'];
$query = "SELECT nama_file, filedata FROM upload WHERE id_file='$id'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
$uploadedFileName = $row['nama_file'];
// Load RSA private key
$privateKeyFileName = pathinfo($uploadedFileName, PATHINFO_FILENAME) . "_private_key.pem";
$privateKey = file_get_contents('./keys/'. $privateKeyFileName);
// Decrypt AES key using RSA private key
$encryptedAesKeyFileName = pathinfo($uploadedFileName, PATHINFO_FILENAME) . "_encrypted_aes_key.bin";
$encAesKey = file_get_contents('./keys/'. $encryptedAesKeyFileName);
openssl_private_decrypt($encAesKey, $decAesKey, $privateKey);
// Load encrypted data from the database (Assuming you have a function to retrieve data from the database)
$encryptedData = $row['filedata'];
// Decrypt data using AES
$iv = substr($encryptedData, 0, 16);
$ciphertext = substr($encryptedData, 16);
$plaintext = openssl_decrypt($ciphertext, 'aes-128-cbc', $decAesKey, 0, $iv);
// Prepare file for download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($uploadedFileName));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . strlen($plaintext));
ob_clean();
flush();
echo $plaintext;
// exit;
} else {
echo "File name not provided.";
}
?>