介紹

此章節介紹在 Php 中如何實作密碼學中,以對稱式為主的加解密,包含應用在CBC、OFB、CFB and ECB四種Cipher Modes的DES、TripleDES、Blowfish (default)、3-WAY、SAFER-SK64 …. 等等2x種的Block Algorithm。

官方網址為 : [http://tw2.php.net/mcrypt http://tw2.php.net/mcrypt]

需求

Mcrypt的前身是Crypt,官方文件已經不建議使用,語法上大致相似,不過功能卻更多,以PHP5為例,Linux環境的使用者建議使用 Libmcrypt2.5.6或以上的版本,Windows環境可以直接使用已經包裝好的Dll檔案

:Linux平台libmcrypt-x.x.tar.gz 檔 [http://mcrypt.sourceforge.net/ http://mcrypt.sourceforge.net/]

:Windows平台Dll 檔 [http://files.edin.dk/php/win32/mcrypt/ http://files.edin.dk/php/win32/mcrypt/]

ps1. PHP5 的Windows Binaries資料夾,在ext資料夾內已經有包含一個php_mcrypt.dll檔案,可直接使用,記得將php.ini內的;extension =php_mcrypt.dll註解;拿掉,並確定extension_dir的資料夾有指向php_mcrypt.dll所在的資料夾

ps2. 設定完以後,記得將服務全部重開!

檢視可用功能

這個語法可以檢視一下目前設定可支援的演算法及模式有哪些

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>

<html>
<head>
<meta equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>PHP Page</title>
</head>
<body>
<?php
// ===============================
// 顯示目前系統支援的 Block algorithms
// ===============================
echo “顯示目前系統支援的 Block algorithms”;
echo ‘<pre>’ . print_r(mcrypt_list_algorithms(), TRUE) . ‘</pre>’;

// ===============================
// 顯示目前系統支援的 Mode
// ===============================
echo “顯示目前系統支援的 Mode”;
echo ‘<pre>’ . print_r(mcrypt_list_modes(), TRUE) . ‘</pre>’;
?>
</body>
</html>

範例說明

* 對稱式加密 (Symmetric Encryption)

在 Symmetric Encryption 中,通訊雙方所使用的金鑰為同一把;因此在範例程式中,會先產生一把金鑰,並針對特定訊息進行加解密以比較結果。

* Electronic Cipher Block (ECB)

以下為範例程式碼:

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>

<html>
<head>
<meta equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>PHP Page</title>
</head>
<body>
<?php
// ===============================
// 初始化資料
// ===============================
$key = “許功蓋碁堃 ABCDEFG”;
$input = “這邊是要需要被隱藏的文件資料 ( 許功蓋碁堃 )ABCDEFG”;

// ===============================
// 實做
// string mcrypt_ecb ( int $cipher , string $key , string $data , int $mode )
// This function is deprecated and should not be used anymore, see mcrypt_generic() and mdecrypt_generic() for replacements.
// ===============================
$crypttext = mcrypt_ecb(MCRYPT_RIJNDAEL_256, $key, $input, MCRYPT_DECRYPT);
$recoverCrypttext = mcrypt_ecb(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_ENCRYPT);

// ===============================
// 顯示結果
// ===============================
echo “<b>原始資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $input.”<br/><br/>”;

echo “<b>加密資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $crypttext.”<br/>”;
echo base64_encode($crypttext).”<br/><br/>”;

echo “<b>還原後的資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $recoverCrypttext.”<br/>”;
echo rtrim($recoverCrypttext, “”).”<br/><br/>”;

echo “<p style=”‘color:red'”>!! The data is padded with “\0″ to make sure the length of the data is n * blocksize.</p>”;
echo “solutions: 1.use strlen(xxxxxxx….. 2.rtrim(xxxx, “\0″)”;
?>
</body>
</html>

* 目前建議使用的加解密語法一

在 block cipher 的 algorithm mode 中,為了防止同樣的訊息加密後被猜出來,因此出現了 CBC、CFB、OFB …. 等等不同的 algorithm mode。

但這些 mode 的特色是必須要有一個 Initial Vector 的輔助來達成這個目的,以下用一段程式法來示範:

ps.ECB也有支援!!

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>

<html>
<head>
<meta equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>JSP Page</title>
</head>
<body>
<?php
// ===============================
// 初始化資料
// ===============================
$key = “許功蓋碁堃 ABCDEFG”;
$input = “這邊是要需要被隱藏的文件資料 ( 許功蓋碁堃 )ABCDEFG”;

// ===============================
// 產生input vator
// ===============================
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

// ===============================
// 實做
// ===============================
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $input, MCRYPT_MODE_CBC, $iv);
$recoverCrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_CBC, $iv);

// ===============================
// 顯示結果
// ===============================
echo “<b>原始資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $input.”<br/><br/>”;

echo “<b>加密資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $crypttext.”<br/>”;
echo base64_encode($crypttext).”<br/><br/>”;

echo “<b>還原後的資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $recoverCrypttext.”<br/>”;
echo rtrim($recoverCrypttext, “”).”<br/><br/>”;
?>
</body>
</html>

* 目前建議使用的加解密語法二

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>

<html>
<head>
<meta equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>JSP Page</title>
</head>
<body>
<?php
// ===============================
// 初始化資料
// ===============================
$key = “許功蓋碁堃 ABCDEFG”;
$input = “這邊是要需要被隱藏的文件資料 ( 許功蓋碁堃 )ABCDEFG”;

// ===============================
// 產生mode和input vator
// ===============================
$td = mcrypt_module_open(‘tripledes’, ”, ‘cbc’, ”);
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);

//加密
$crypttext = mcrypt_generic($td, $input);
//還原
$recoverCrypttext = mdecrypt_generic($td, $crypttext);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

// ===============================
// 顯示結果
// ===============================
echo “<b>原始資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $input.”<br/><br/>”;

echo “<b>加密資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo $crypttext.”<br/>”;
echo base64_encode($crypttext).”<br/><br/>”;

echo “<b>還原後的資料:</b>”.”<br/>”;
echo “———————————————–“.”<br/>”;
echo rtrim($recoverCrypttext, “”).”<br/><br/>”;
?>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *