PHP Conference Japan 2024

Mcrypt 函數

目錄

新增筆記

使用者貢獻的筆記 24 筆筆記

3
rolf at winmutt dot com
18 年前
適用於 PHP 的 mysql AES_ENCRYPT() 相容函數

<?php
function mysql_aes_encrypt($val,$ky) {
$mode=MCRYPT_MODE_ECB;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return
mcrypt_encrypt($enc, $ky, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM));
}
?>

請注意,如果 strlen($ky)>16,則此函數將不相容。
3
groundzero at zuavra dot net
20 年前
如果您曾經從原始碼編譯 PHP(任何版本),您可能熟悉當您嘗試編譯 --with-mcrypt 時出現的 [惡名昭彰] 的 MCRYPT_BLOWFISH_128 編譯錯誤。它經常發生在 Debian 上,但不只在那裡。問題:在編譯期間,PHP configure 腳本總是假設 libmcrypt 是與 libltdl 結合建置的。每當不是這樣的情況時,PHP 編譯稍後將會失敗,並顯示某些標頭(例如上面的 blowfish 範例)在 mcrypt.h 中遺失(這是誤導的,它們不應該在那裡,如果 libltdl 正常參與也不應該被查找)。解決方案:確保您的 libmcrypt 在您開始設定 PHP 之前已連結到 libltdl。您可以執行 'ldd lybmcrypt.so' 並驗證 libltdl 出現在輸出中來檢查。libltdl 可以在 Debian 上的 libltld[3][-dev] 或 Red Hat 上的 libtool-libs 中找到。
4
manyagain
15 年前
如果您沒有安裝 mcrypt,請嘗試 phpseclib - http://phpseclib.sourceforge.net

包含 des、3des、rc4、aes 和 rijndael 的純 PHP 實作。如果可用則使用 mcrypt,否則使用純 PHP 實作。它還具有文件 3.5.5 節「速度比較」中現有的最快純 PHP aes 實作的區別。
5
duerra_NOT_THIS_ at pushitlive dot net
18 年前
對於那些需要使用 PKCS#5 填充的人,PHP 的 mcrypt API 不支援它。但是,您可以使用以下方式 DIY

<?php

function encrypt_something($input)
{
$size = mcrypt_get_block_size('des', 'ecb');
$input = pkcs5_pad($input, $size);

$key = 'YOUR SECRET KEY HERE';
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
return
$data;
}

function
pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return
$text . str_repeat(chr($pad), $pad);
}

function
pkcs5_unpad($text)
{
$pad = ord($text{strlen($text)-1});
if (
$pad > strlen($text)) return false;
if (
strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return
substr($text, 0, -1 * $pad);
}
?>
2
triptripon at gmail dot com
18 年前
關於將結果儲存在使用 Unicode 的 postgres 資料庫中(接續下面的貼文)。
您不需要將資料庫的編碼更改為 ASCII。
只需使用 BASE64 編碼結果,這樣做是完全安全的。
解密前請使用 base64_decode。
-- Tomer Levinboim
2
herowekker at hotmail dot com
21 年前
使用 base64_decode 的 mcrypt_ecb 遇到了一些問題,我發現它必須被截斷才能運作

<?php
chop
(mcrypt_ecb(MCRYPT_BLOWFISH,$key,base64_decode($input),MCRYPT_DECRYPT));
?>
1
Kevin
16 年前
問題已解決

當編譯 php --with-mcrypt 時,phpinfo() 顯示 mcrypt 已啟用,但是
「支援的加密演算法:無」和
「支援的模式:無」

為了讓 mcrypt 在 php 中運作,您必須使用以下選項設定並編譯 libmcrypt 原始碼套件
./configure --disable-posix-threads --enable-dynamic-loading
1
simms
21 年前
DEBIAN 使用者:避免 mcrypt 安裝上的麻煩。
要將 mcrypt 支援新增到現有的 php 安裝中,請取得 root 權限並執行

apt-get install php4-mcrypt

重新啟動您的網站伺服器,就完成了。
1
pawelNOSPAM at rsc dot pl
23 年前
如果您在沒有問題的情況下編譯了 mcrypt 和 php,但 phpinfo() 顯示沒有支援的加密演算法和模式,請嘗試將 libdirs 的模式更改為 755 (/usr/local/libmcrypt, /usr/local/libcrypt)。
1
patrickdk at patrickdk dot com
14 年前
這與 mysql aes 完全相容,即使是很長的金鑰也沒問題。

<?php
function mysql_aes_decrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for(
$a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode = MCRYPT_MODE_ECB;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $key, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM ) );
return
rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
}

function
mysql_aes_encrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for(
$a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode=MCRYPT_MODE_ECB;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return
mcrypt_encrypt($enc, $key, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM));
}
?>
1
mountie at paygate dot net
24 年前
加密後的結果資料可能是二進位資料,這會在 sql 查詢中產生錯誤。
因此請將 base64_encode/base64_decode 函數與 mcrypt() 一起使用
嘗試以下操作

<?php
base64_encode
(mcrypt_ecb(MCRYPT_BLOWFISH,$key,$input,MCRYPT_ENCRYPT));

mcrypt_ecb(MCRYPT_BLOWFISH,$key,base64_decode($input),MCRYPT_DECRYPT);
?>
0
p ete postma - googlemail.com
15 年前
mcrypt 模組初始化失敗

我發現這種情況

usemcrypt.php
<?php
function protect() {
//一些 mcrypt/decrypt 命令
}
?>

filea.php
<?php
include_once('usemcrypt.php');

function
a() {
protect();
}
?>

fileb.php
<?php
function b() {
include_once(
'usemcrypt.php');
protect();
}
?>

filea.php 和 a() 可以正常運作
fileb.php 和 b() 會回報 mcrypt 模組初始化失敗

我假設你不能在執行時載入該模組。如果你使用一個呼叫 mcrypt 的檔案,它必須在檔案頭部被引入,而不是在函式中。
0
Rafael M. Salvioni
16 年前
以下函式是以純 PHP 程式碼實作的 RC4 加密演算法。

此函式用於加密和解密資料。

<?php
/**
* 使用 RC4 串流加密演算法加密/解密字串。
*
* @param string $key 金鑰
* @param string $data 已加密/原始資料
* @see http://pt.wikipedia.org/wiki/RC4
* @return string
*/
function rc4($key, $data)
{
// 儲存已計算的向量 "S"
static $SC;
// 交換向量 "S" 值的函式
$swap = create_function('&$v1, &$v2', '
$v1 = $v1 ^ $v2;
$v2 = $v1 ^ $v2;
$v1 = $v1 ^ $v2;
'
);
$ikey = crc32($key);
if (!isset(
$SC[$ikey])) {
// 根據金鑰建立向量 "S"
$S = range(0, 255);
$j = 0;
$n = strlen($key);
for (
$i = 0; $i < 255; $i++) {
$char = ord($key{$i % $n});
$j = ($j + $S[$i] + $char) % 256;
$swap($S[$i], $S[$j]);
}
$SC[$ikey] = $S;
} else {
$S = $SC[$ikey];
}
// 加密/解密資料
$n = strlen($data);
$data = str_split($data, 1);
$i = $j = 0;
for (
$m = 0; $m < $n; $m++) {
$i = ($i + 1) % 256;
$j = ($j + $S[$i]) % 256;
$swap($S[$i], $S[$j]);
$char = ord($data[$m]);
$char = $S[($S[$i] + $S[$j]) % 256] ^ $char;
$data[$m] = chr($char);
}
return
implode('', $data);
}
?>
0
Ivan Frederiks
17 年前
要在 Windows 下啟用 mcrypt 擴充功能,您需要執行以下操作:
1) 在 php.ini 中取消註解 "extension=php_mcrypt.dll" 這行
2) 從 http://files.edin.dk/php/win32/mcrypt/ 下載 libmcrypt.dll 並將其放入 System32 目錄(例如 C:\Windows\System32)。
已在 Windows XP+Apache 1.3.37+PHP 4.4.6(作為 SAPI 模組!!!)上測試。

P.S.
我寫這個是因為當我簡單地取消註解 "extension=php_mcrypt.dll" 這行時,我從 phpMyAdmin 得到「無法載入 mcrypt 擴充功能。請檢查您的 PHP 設定」。
0
vincent at verbrugh dot nl
18 年前
如果您打算使用 Mcrypt 加密來儲存加密資料(例如密碼)在 (MySQL) 資料庫中,請務必將資料行設定為 BLOB 而不是 VARCHAR。否則資料可能會變更,如果您解密該值,可能會產生意想不到的結果。
0
Jerry Hathaway
18 年前
在對 256 位元運算的 AES 進行基準測試後,我得出結論,CBC 比 OFB 快得多。使用 14.9 MiB 的檔案,平均而言...

在 CBC 中加密:1.9 秒
在 OFB 中加密:45.7 秒(與 CFB 相同)
僅讀取檔案:~0.53 秒

經過一些研究,我得出結論,OFB 和 CFB 比 CBC 略為安全,但我認為效能差異是由於實作問題。

關於 ECB 的附註:如以下連結的維基中所述,ECB 完全不適用。它不使用 IV(無論是否提供給 MCrypt),這表示相同的金鑰和明文總是會產生相同的密文,並且不會隱藏模式。該網站顯示了一個很好的例子。

非常有用的資訊
http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
0
coz AT metamule D0T com
19 年前
如果您要使用類似這樣的東西加密資料並將其儲存在 postgres 中。

<?php
function encrypt($string, $key){
$result = '';
for(
$i=1; $i<=strlen($string); $i++){
$char = substr($string, $i-1, 1);
$keychar = substr($key, ($i % strlen($key))-1, 1);
$char = chr(ord($char)+ord($keychar));
$result.=$char;
}
return
$result;
}
?>

當您建立資料庫時,請務必將編碼設定為 SQL_ASCII,因為您將無法在 使用 UNICODE 的資料庫中儲存此資料
0
joseph-at-digiweb-dot-net-dot-nz
19 年前
給那些在 PHP 和 Java 之間進行互通操作的人的進一步說明

如果您在 Java 端使用 BouncyCastle 函式庫,那麼您現在可以使用其中提供的 ZeroBytePadding 模式。Mcrypt 使用 Null 而不是空格來填充資料...

我已成功地透過這種方式在 PHP 和 Java 之間使用 Blowfish/CBC/ZeroBytePadding 進行互通操作。
0
paul dot lewis at absolutegenius dot co dot uk
19 年前
我花了一整天試圖讓 mcrypt 在 Windows Server 2003 (Web Edition) 的 IIS6 環境下,與 PHP 5.0.4 協同運作。

當你在這個環境中以 ISAPI 模式執行 PHP 時,啟用某些擴充功能(mcrypt 就是其中之一)似乎存在一些不相容的問題。

解決這個問題的方法(錯誤訊息會顯示無法載入 php_mcrypt.dll - 存取被拒絕)是以 CGI 模式執行。雖然這樣在效能上可能不如 ISAPI,但如果你需要 mcrypt 支援(或是 Oracle 支援,我想也是),這是目前我找到唯一可行的方法。
0
Jurgen Schwietering
20 年前
請注意當使用長度超過實際金鑰大小的金鑰時(例如 160 位元而不是 128 位元)。

雖然在 PHP 腳本之間運作正常,但當結合 openssl 或其他套件使用 mcrypt 時,可能會產生問題。請務必將金鑰截斷為支援的大小 (mcrypt_enc_get_key_size) ,以避免熬夜。
0
scott at boothcreek dot com
22 年前
如果你使用 ECB 模式加密,它似乎不太使用 iv (初始化向量),給定相同的金鑰,無論 iv 是什麼,它總是會解密。如果你使用 CBC 模式,你必須使用加密時相同的 iv 進行解密。

如果在解密前使用不同的 iv,你的解密將無法運作。我認為使用 CBC 模式比 ECB 模式更好,因為 ECB 模式對於相同的明文總是加密成相同的密文(使你容易受到已知明文攻擊)。 CBC 模式使用隨機的 iv,這意味著文字會加密成不同的東西。你或許可以透過在 ECB 模式中使用隨機金鑰來達到相同的效果。

我是在 Schneier 的書 - Applied Cryptography (ISBN 0-471-11709-9) 中讀到這個的。對於任何認真使用任何類型加密的人來說,這本書都是必讀的。
-1
phpknights at pookmail dot com
16 年前
Pear 類別 Crypt/Blowfish.php 如果可用,會使用 mcrypt 模組,但 mcrypt 模組不是必須的。

一些非常簡單的 Pear 和虛擬碼範例,可透過使用單向雜湊和 Blowfish 對稱加密來保護你的資料庫。
http://en.wikibooks.org/wiki/Cryptography/Database_protection

使用單向雜湊和 Blowfish 對稱加密。
1. 在加密的資料庫中插入 John Doe 的記錄。
2. 取得使用者 John Doe 的加密記錄並解密資料。

1. 在加密的資料庫中插入 John Doe 的記錄。
<?php

require_once("Crypt/Blowfish.php"); // a Pear class

$aRecord['email'] = "johndoe@anisp.localhost"; // The Primary key
$aRecord['name'] = "John Doe";
$aRecord['creditnr'] = "0192733652342" ;

// crypt - 單向加密
$cipher_key = crypt( $aRecord['email'] , "AN_SECRET_COMPANY_SALT");

$bf = new Crypt_Blowfish('ecb');
$bf->setKey( $cipher_key );

// crypt_blowfish 對稱加密以加密資料
$aRecord['email'] = $bf->encrypt( $aRecord['email'] );
$aRecord['name'] = $bf->encrypt( $aRecord['name'] );
$aRecord['creditnr'] = $bf->encrypt( $aRecord['creditnr'] );

$result = sqlInsert( $aRecord ) ;
?>

2. 取得使用者 John Doe 的加密記錄並解密資料。
<?php

require_once("Crypt/Blowfish.php"); // a Pear class

$primary_key = "johndoe@anisp.localhost";

// crypt - 單向加密
$cipher_key = crypt( $primary_key , "AN_SECRET_COMPANY_SALT");

$bf = new Crypt_Blowfish('ecb');
$bf->setKey( $cipher_key );

// crypt_blowfish 對稱加密以加密主鍵,用於 sql 選擇
$select_key = $bf->encrypt( $primary_key ) ;

$aRecord = sqlSelectWithPKEY( $select_key );

// crypt_blowfish 對稱加密以解密資料
$aRecord['email'] = $bf->decrypt( $aRecord['email'] );
$aRecord['name'] = $bf->decrypt( $aRecord['name'] );
$aRecord['creditnr'] = $bf->decrypt( $aRecord['creditnr'] );
?>

感謝你的閱讀。
-1
artem at it-nt dot ru
16 年前
以下是一些用於 LM 雜湊的程式碼

<?php
function LMhash($string)
{
$string = strtoupper(substr($string,0,14));

$p1 = LMhash_DESencrypt(substr($string, 0, 7));
$p2 = LMhash_DESencrypt(substr($string, 7, 7));

return
strtoupper($p1.$p2);
}

function
LMhash_DESencrypt($string)
{
$key = array();
$tmp = array();
$len = strlen($string);

for (
$i=0; $i<7; ++$i)
$tmp[] = $i < $len ? ord($string[$i]) : 0;

$key[] = $tmp[0] & 254;
$key[] = ($tmp[0] << 7) | ($tmp[1] >> 1);
$key[] = ($tmp[1] << 6) | ($tmp[2] >> 2);
$key[] = ($tmp[2] << 5) | ($tmp[3] >> 3);
$key[] = ($tmp[3] << 4) | ($tmp[4] >> 4);
$key[] = ($tmp[4] << 3) | ($tmp[5] >> 5);
$key[] = ($tmp[5] << 2) | ($tmp[6] >> 6);
$key[] = $tmp[6] << 1;

$is = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($is, MCRYPT_RAND);
$key0 = "";

foreach (
$key as $k)
$key0 .= chr($k);
$crypt = mcrypt_encrypt(MCRYPT_DES, $key0, "KGS!@#$%", MCRYPT_MODE_ECB, $iv);

return
bin2hex($crypt);
}
?>

有什麼最佳化的空間嗎?
-2
steve@itemfront dot ltd dot uk
21 年前
花了一點時間讓 mcrypt 支援在 php 上正常運作。使用了 libmcrypt 版本 2.5.7 和 php 4.3.3。直接使用預設設定是無法運作的。請依照以下方式設定

libmcrypt

./configure --disable-posix-threads --enable-dynamic-loading

php: ( 如你所見,它是為 SunONE 伺服器建構的,但這部分很容易設定!)

./configure --with-nsapi=/usr/iplanet/servers --enable-sigchld --with-ldap --with-zlib-dir=/usr/lib --with-mcrypt=<srcdir>/libmcrypt-2.5.7

希望對你有幫助,steve
To Top