手把手 PHP 針對上傳檔案做 AES 加解密教學。
各位看倌,若是對 Aes 不太了解可以看這篇呦。
事前準備
需要各位看倌,請先幫我準備好 PHP 執行環境並建立同下圖的資料結構。
boss_o.jpeg
是一張由 Google 上抓取的圖片,作為範例檔案使用。
decode
放置解密後資料位置。
encrypt
放置加密後資料位置。
index.php
主程式,實作程式內部邏輯。
來點簡單的檔案上傳
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php # 檔案上傳邏輯 if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file']) && $_FILES['file']['error'] == 0) { $file = $_FILES['file']['tmp_name'];
# 檔案位置 $dest = 'encrypt/' . $_FILES['file']['name'];
# 將檔案移至指定位置 move_uploaded_file($file, $dest);
echo '上傳成功' . '</br>'; } ?>
<form method="post" enctype="multipart/form-data"> <input type="file" id="file" name="file" /> <button>Submit</button> </form>
|
只是一個簡單的檔案上傳邏輯,確保上傳檔案有成功放至資料夾 encrypt
內。
將上傳的檔案做加密的動作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?php # 加密 function encrypt($key, $payload) { $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); $encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv); return base64_encode($encrypted . '::' . $iv); }
# 寫入檔案 function setFile($msg, $dest) { //取出目錄路徑中目錄(不包括後面的檔案) $dir_name = dirname($dest);
//如果目錄不存在就建立 if(!file_exists($dir_name)) { mkdir(iconv("UTF-8", "GBK", $dir_name), 0777, true); }
//開啟檔案資源通道,不存在則自動建立 $fp = fopen($dest, "w");
//寫入檔案 fwrite($fp, $msg);
//關閉資源通道 fclose($fp); }
# 檔案上傳邏輯 if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file']) && $_FILES['file']['error'] == 0) { $file = $_FILES['file']['tmp_name'];
$dest = 'encrypt/' . $_FILES['file']['name']; $e = encrypt('testKey', file_get_contents($file)); setFile($e, $dest);
echo '上傳成功' . '</br>'; } ?>
<form method="post" enctype="multipart/form-data"> <input type="file" id="file" name="file" /> <button>Submit</button> </form>
|
此處將上傳的檔案內容取出做 AES 加密的行為,再將加密資料存回檔案。
- 透過
openssl_encrypt
加密內部資料,再由 base64_encode
將加密資料進行編碼以便儲存。
- 此處筆者將
iv 值
放置加密資料後面,方便解密。
setFile
是簡單的建立檔案並寫入內容邏輯。
將加密過的檔案做解密的動作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <?php # 解密 function decode($key, $garble) { list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2); return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv); }
# 寫入檔案 function setFile($msg, $dest) { //取出目錄路徑中目錄(不包括後面的檔案) $dir_name = dirname($dest);
//如果目錄不存在就建立 if(!file_exists($dir_name)) { mkdir(iconv("UTF-8", "GBK", $dir_name), 0777, true); }
//開啟檔案資源通道,不存在則自動建立 $fp = fopen($dest, "w");
//寫入檔案 fwrite($fp, $msg);
//關閉資源通道 fclose($fp); }
# 檔案上傳邏輯 if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file']) && $_FILES['file']['error'] == 0) { $file = $_FILES['file']['tmp_name'];
$dest = 'decode/' . $_FILES['file']['name']; $d = decode('testKey', file_get_contents($file)); setFile($d, $dest);
echo '上傳成功' . '</br>'; } ?>
<form method="post" enctype="multipart/form-data"> <input type="file" id="file" name="file" /> <button>Submit</button> </form>
|
上傳加密後的檔案,並透過 base64_decode
及 openssl_decrypt
逆向將檔案解密出來。若正確解密的話能在資料夾 decode
內看到解密後的檔案。
- 注意加密及解密時的
Key
要是一至的。
- 由於
iv 值
被存於加密後檔案後面,實作上只要管控好 Key
就好。
後話
由於 file_get_contents
是將檔案內容全部存於記憶體內,所以要注意檔案大小及 PHP
開放記憶體是否充足。
加解密 key
及 iv
數值保管,可由看倌們自行決定。
上述為普通的加解密邏輯實作及介紹,懶人包可直接抓取 CODE。