最近兩年一直從事與金融相關項目的開發與維護。但是,關於 PHP 加密解密的最佳實踐,網上沒有人給出一個完美的總結。恰逢最近看了《圖解密碼技術》一書,對 PHP 加解密有了更深刻的認識。
為了避免各位看枯燥的文字理論,開篇我就把總結給出:
一、對稱加密
對稱加密的特點是加解密速度快,加密後的密文強度目前還沒有硬解的可能性。但是,在未來隨著計算機性能的提升有可能會出現被破解的可能性。
對稱加密的缺點也很明顯。對稱加密的加密過程與解密過程使用的是同一把密鑰。一旦泄漏密鑰,加密就失去了任何意義。
根據《圖解密碼技術》一書的推薦,對稱加密目前推薦使用 AES。在 PHP 當中要實現 AES 加解密,是使用 openssl 擴展來實現。所以,請確保你的 PHP 已經開啟了 openssl 擴展。
可以通過如下方式檢測:
或者如下方式檢測:
AES 的加密模式屬於分組密碼模式。所謂分組密碼,是加密時把明文按照固定的長度分組,然後再進行加密。當然,細節之處很很多不同。AES 分組模式有多種:ECB、CBC、CFB、OFB、CTR 五種分組模式。目前優先推薦使用 CBC 模式。
如果使用 CBC 模式,那麼在加密的時候,就需要一個前置的加密向量 IV。當初博主在使用 AES 來加密的時候,就很奇怪一個對稱加密為何要這個向量。因為,在博主寒冰的潛意識里,對稱加密只需要一個密鑰就 Ok 了。沒想到 AES 加密還有多種模式,而這個 CBC 模式恰恰就需要一個這樣的向量值。關於這個向量大家可以在網上查閱相關的資料。這個東西非常重要,也非常好理解。
關於 PHP AES 加解密會用到的相關方法:
AES 支持三種強度:128、192、256。128 位的強度最低,但是,加密解密速度較快。256 位強度最高,但是,加密解密速度最低。所以,大家根據自己系統的重要程度選擇使用對應強度。通常普通的金融項目使用 192 位完整夠用了。頂級的就用 256 位。其他的就用 128 位吧。
二、非對稱加密
非對稱加密是指公鑰加密私鑰解密,私鑰加密公鑰解密的演算法。非對稱加密的演算法有很多。《圖解密碼技術》一書推薦使用 RSA 演算法。它使用起來也非常簡單。
要使用 RSA 演算法。首先,我們必須生成一對公鑰私鑰。其實生成公鑰私鑰很簡單。
在 Linux 系統,直接使用如下命令生成:
此命令會生 ~/.ssh/ 目錄下生成兩個文件:
id_rsa 是私鑰, is_rsa.pub 是公鑰。
關於 PHP RSA 加解密會用到的相關方法:
以上就是關於在 PHP 項目開發中,我們使用的加密解密演算法的一個總結。博主寒冰在總結過程中難免會有不足之處,還請大家指正!謝謝!
⑵ 請教高手,如何解密用zend加密的php文件,已嘗試多種解密軟體還是不行,懇請高手幫忙!QQ:460602396
Zend加密的時候,如果版本在Zend Guard5.0以上,同時在配置設置里選擇以PHP5.3作為目標程序的版本來做加密的話,目前所有的Dezend內核都是無法解密的,直接不做任何處理。但目前運用廣泛的還是PHP5.2.x的版本,所以從兼容角度來看選擇PHP5.3來做Zend加密的並不多,實在不巧遇上了,也只能是放棄,目前沒有解密辦法。
另外一種解密不了的情況是,無論使用多高版本的Zend Guard,加密時使用PHP5.2.x作為目標版本(也就是使用PHP5.2.x來做開發,然後用Zend來加密,加密時有選項的),經過一些特殊處理以後,讓dezend工具試圖解密這些被加密的PHP程序,就出現代碼溢出,無法解密出源碼來,也能很好的保護代碼,而且Zend組件幾乎所有的伺服器或者虛擬主機都能安裝支持,兼容性就非常好了。
另外,看到有朋友說到易維這個加密工具,易維是使用自己的loader了,也是一套新的PHP加密程序,並不是所有的虛擬主機提供商的伺服器上都有安裝相應的loader,所以目前普及性還很不理想。如果一個PHP開發商或者開發者購買了這個易維的加密工具,那就需要要求他們所開發的PHP程序的用戶具有獨立主機或者VPS,用虛擬主機的用戶就得靠邊了。
⑶ PHP對稱加密-AES
對稱加解密演算法中,當前最為安全的是 AES 加密演算法(以前應該是是 DES 加密演算法),PHP 提供了兩個可以用於 AES 加密演算法的函數簇: Mcrypt 和 OpenSSL 。
其中 Mcrypt 在 PHP 7.1.0 中被棄用(The Function Mycrypt is Deprecated),在 PHP 7.2.0 中被移除,所以即可起你應該使用 OpenSSL 來實現 AES 的數據加解密。
在一些場景下,我們不能保證兩套通信系統都使用了相函數簇去實現加密演算法,可能 siteA 使用了最新的 OpenSSL 來實現了 AES 加密,但作為第三方服務的 siteB 可能仍在使用 Mcrypt 演算法,這就要求我們必須清楚 Mcrypt 同 OpenSSL 之間的差異,以便保證數據加解密的一致性。
下文中我們將分別使用 Mcrypt 和 OpenSSL 來實現 AES-128/192/256-CBC 加解密,二者同步加解密的要點為:
協同好以上兩點,就可以讓 Mcrypt 和 OpenSSL 之間一致性的對數據進行加解密。
AES 是當前最為常用的安全對稱加密演算法,關於對稱加密這里就不在闡述了。
AES 有三種演算法,主要是對數據塊的大小存在區別:
AES-128:需要提供 16 位的密鑰 key
AES-192:需要提供 24 位的密鑰 key
AES-256:需要提供 32 位的密鑰 key
AES 是按數據塊大小(128/192/256)對待加密內容進行分塊處理的,會經常出現最後一段數據長度不足的場景,這時就需要填充數據長度到加密演算法對應的數據塊大小。
主要的填充演算法有填充 NUL("0") 和 PKCS7,Mcrypt 默認使用的 NUL("0") 填充演算法,當前已不被推薦,OpenSSL 則默認模式使用 PKCS7 對數據進行填充並對加密後的數據進行了 base64encode 編碼,所以建議開發中使用 PKCS7 對待加密數據進行填充,已保證通用性(alipay sdk 中雖然使用了 Mcrypt 加密簇,但使用 PKCS7 演算法對數據進行了填充,這樣在一定程度上親和了 OpenSSL 加密演算法)。
Mcrypt 的默認填充演算法。NUL 即為 Ascii 表的編號為 0 的元素,即空元素,轉移字元是 " ",PHP 的 pack 打包函數在 'a' 模式下就是以 NUL 字元對內容進行填充的,當然,使用 " " 手動拼接也是可以的。
OpenSSL的默認填充演算法。下面我們給出 PKCS7 填充演算法 PHP 的實現:
默認使用 NUL(" ") 自動對待加密數據進行填充以對齊加密演算法數據塊長度。
獲取 mcrypt 支持的演算法,這里我們只關注 AES 演算法。
注意:mcrypt 雖然支持 AES 三種演算法,但除 MCRYPT_RIJNDAEL_128 外, MCRYPT_RIJNDAEL_192/256 並未遵循 AES-192/256 標准進行加解密的演算法,即如果你同其他系統通信(java/.net),使用 MCRYPT_RIJNDAEL_192/256 可能無法被其他嚴格按照 AES-192/256 標準的系統正確的數據解密。官方文檔頁面中也有人在 User Contributed Notes 中提及。這里給出如何使用 mcrpyt 做標注的 AES-128/192/256 加解密
即演算法統一使用 MCRYPT_RIJNDAEL_128 ,並通過 key 的位數 來選定是以何種 AES 標准做的加密,iv 是建議添加且建議固定為16位(OpenSSL的 AES加密 iv 始終為 16 位,便於統一對齊),mode 選用的 CBC 模式。
mcrypt 在對數據進行加密處理時,如果發現數據長度與使用的加密演算法的數據塊長度未對齊,則會自動使用 " " 對待加密數據進行填充,但 " " 填充模式已不再被推薦,為了與其他系統有更好的兼容性,建議大家手動對數據進行 PKCS7 填充。
openssl 簇加密方法更為簡單明確,mcrypt 還要將加密演算法分為 cipher + mode 去指定,openssl 則只需要直接指定 method 為 AES-128-CBC,AES-192-CBC,AES-256-CBC 即可。且提供了三種數據處理模式,即 默認模式 0 / OPENSSL_RAW_DATA / OPENSSL_ZERO_PADDING 。
openssl 默認的數據填充方式是 PKCS7,為兼容 mcrpty 也提供處理 "0" 填充的數據的模式,具體為下:
options 參數即為重要,它是兼容 mcrpty 演算法的關鍵:
options = 0 : 默認模式,自動對明文進行 pkcs7 padding,且數據做 base64 編碼處理。
options = 1 : OPENSSL_RAW_DATA,自動對明文進行 pkcs7 padding, 且數據未經 base64 編碼處理。
options = 2 : OPENSSL_ZERO_PADDING,要求待加密的數據長度已按 "0" 填充與加密演算法數據塊長度對齊,即同 mcrpty 默認填充的方式一致,且對數據做 base64 編碼處理。注意,此模式下 openssl 要求待加密數據已按 "0" 填充好,其並不會自動幫你填充數據,如果未填充對齊,則會報錯。
故可以得出 mcrpty簇 與 openssl簇 的兼容條件如下:
建議將源碼復制到本地運行,根據運行結果更好理解。
1.二者使用的何種填充演算法。
2.二者對數據是否有 base64 編碼要求。
3.mcrypt 需固定使用 MCRYPT_RIJNDAEL_128,並通過調整 key 的長度 16, 24,32 來實現 ase-128/192/256 加密演算法。
⑷ 這是PHP什麼加密方式 如何解密
zend的加密完全可以破解,網上可以下載在zend解密的東西,打開後選擇文件就可以給你解密(但是不是全部能解,因為zend是有版本的,高版本的可能解不了。)
如果是base64加密的你,例如$a是被加密過後的字元串,那麼你可以echo base64_decode($a);來查看。base64實際上並不是加密,只是一個編碼而已。
⑸ 前端使用CryptoJS AES加密 ,後端php解密問題
PHP7.1 已經不能用mcrypt了,所以我用的是openssl_encrypt和openssl_decrypt。
<?php
$data="ThisisanAEScryptdemo.";
$privateKey="";//KEY16位元組用aes-128-cbc,32位元組用aes-256-cbc
$iv="4490d2ded4f2d4ad";//AES的IV是16個位元組
//加密
//$encrypted=openssl_encrypt($data,'aes-128-cbc',$privateKey,0,$iv);
$encrypted=openssl_encrypt($data,'aes-256-cbc',$privateKey,0,$iv);
echo$encrypted,PHP_EOL;
//解密
$encryptedData=$encrypted;
//$decrypted=openssl_decrypt($encryptedData,'aes-128-cbc',$privateKey,0,$iv);
$decrypted=openssl_decrypt($encryptedData,'aes-256-cbc',$privateKey,0,$iv);
echo($decrypted);
輸出結果如下:
EPcMQRXA53/hRkPyILFI4fF/9sW2X53tLiDT26khNsA=
ThisisanAEScryptdemo.
⑹ php 方面大家一般用哪些工具進行代碼加密
所謂 zend 加密,其實是預編譯
他將 php 代碼翻譯成了一種虛擬機器的指令集合(php 運行時也是這樣,但指令集不同)
所以 zend 解密,實際是反編譯
由於涉及到 php 內核機制,故不在本討論范圍之內
凡是比依賴加密環境的加密,實際都是擾碼——程序依據自身包含的演算法將自身還原成初始的代碼
這種程序最終執行的是還原後的代碼
所以你完全有可能在他運行期間,攔截到包含 還原後代碼 的字元串
由於擾碼的程序,本身是可執行的,所以還可以從語法分析入手
php 提供 token_get_all 函數,用於對 php 代碼串做詞法分析
可得到類似這樣的數組
Plain Text code? [32] => Array ( [0] => T_STRING [1] => T撾CB蜦RW仄JW豎IDFZZD蜺FBAADVAVQU頤HCF頕V厝VN游煁啙 [2] => 2 ) [33] => Array ( [0] => symbol [1] => ; [2] => 2 ) [34] => Array ( [0] => T_STRING [1] => T沃FBAEBAFAIBAQIA?腄AAHU領ABF萉A1FVB仡FB頔A庮葴 [2] => 2 )
依據他,就可對程序做出解析,從而反推出原始代碼
我使用
PHP code?1234<?php$source=file_get_contents('s.php');$tokens = token_get_all ($source ); print_r($tokens);
⑺ java的 DES 加密解密方法 求對應php的加密解密方法!!!!急切
DES是一種標準的數據加密演算法,關於這個演算法的詳細介紹可以參考wiki和網路:
php中有一個擴展可以支持DES的加密演算法,是:extension=php_mcrypt.dll
在配置文件中將這個擴展打開還不能夠在windows環境下使用
需要將PHP文件夾下的 libmcrypt.dll 拷貝到系統的 system32 目錄下,這是通過phpinfo可以查看到mcrypt表示這個模塊可以正常試用了。
下面是PHP中使用DES加密解密的一個例子:
//$input-stufftodecrypt
//$key-thesecretkeytouse
functiondo_mencrypt($input,$key)
{
$input=str_replace(""n","",$input);
$input=str_replace(""t","",$input);
$input=str_replace(""r","",$input);
$key=substr(md5($key),0,24);
$td=mcrypt_mole_open('tripledes','','ecb','');
$iv=mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
mcrypt_generic_init($td,$key,$iv);
$encrypted_data=mcrypt_generic($td,$input);
mcrypt_generic_deinit($td);
mcrypt_mole_close($td);
returntrim(chop(base64_encode($encrypted_data)));
}
//$input-stufftodecrypt
//$key-thesecretkeytouse
functiondo_mdecrypt($input,$key)
{
$input=str_replace(""n","",$input);
$input=str_replace(""t","",$input);
$input=str_replace(""r","",$input);
$input=trim(chop(base64_decode($input)));
$td=mcrypt_mole_open('tripledes','','ecb','');
$key=substr(md5($key),0,24);
$iv=mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
mcrypt_generic_init($td,$key,$iv);
$decrypted_data=mdecrypt_generic($td,$input);
mcrypt_generic_deinit($td);
mcrypt_mole_close($td);
returntrim(chop($decrypted_data));
}
參考自:http://www.cnblogs.com/cocowool/archive/2009/01/07/1371309.html
⑻ 關於php 類似md5那種加密出來全小寫混合數字但是可以解密的函數有沒有
可以使用字元串到16進制和16進制到字元串實現
<?php
echostr_encode("哈123abc-=/*-+=");//顯示:
echostr_decode("");//顯示:哈123abc-=/*-+=
functionstr_encode($string){//字元串轉十六進制
$hex="";
for($i=0;$i<strlen($string);$i++)
$hex.=dechex(ord($string[$i]));
$hex=strtoupper($hex);
return$hex;
}
functionstr_decode($hex){//十六進制轉字元串
$string="";
for($i=0;$i<strlen($hex)-1;$i+=2)
$string.=chr(hexdec($hex[$i].$hex[$i+1]));
return$string;
}
⑼ 80分求DES加密解密演算法實現的PHP源代碼
以下演算法根據js演算法移植:
<?php
function des ($key, $message, $encrypt, $mode, $iv, $padding) {
$message0 = $message;
//declaring this locally speeds things up a bit
$spfunction1 = array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
$spfunction2 = array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
$spfunction3 = array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
$spfunction4 = array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
$spfunction5 = array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
$spfunction6 = array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
$spfunction7 = array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
$spfunction8 = array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
$masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0);
//create the 16 or 48 subkeys we will need
$keys = des_createKeys ($key);
$m=0;
$len = strlen($message);
//如果加密,則需要填充
if($encrypt==1){
if($len%8==1){
for($i=0;$i<7;$i++)
$message.=chr(7);
}
if($len%8==2){
for($i=0;$i<6;$i++)
$message.=chr(6);
}
if($len%8==3){
for($i=0;$i<5;$i++)
$message.=chr(5);
}
if($len%8==4){
for($i=0;$i<4;$i++)
$message.=chr(4);
}
if($len%8==5){
for($i=0;$i<3;$i++)
$message.=chr(3);
}
if($len%8==6){
for($i=0;$i<2;$i++)
$message.=chr(2);
}
if($len%8==7){
for($i=0;$i<1;$i++)
$message.=chr(1);
}
if($len%8==0){
for($i=0;$i<8;$i++)
$message.=chr(8);
$len = $len + 8;
}
}
echo "message:".$message;
echo "<br>";
$chunk = 0;
//set up the loops for single and triple des
$iterations = ((count($keys) == 32) ? 3 : 9); //single or triple des
if ($iterations == 3) {$looping = (($encrypt) ? array (0, 32, 2) : array (30, -2, -2));}
else {$looping = (($encrypt) ? array (0, 32, 2, 62, 30, -2, 64, 96, 2) : array (94, 62, -2, 32, 64, 2, 30, -2, -2));}
echo "3.iterations".$iterations;
echo "<br> 4.looping:";
for($ii = 0; $ii < count($looping); $ii++){
echo ",".$looping[$ii];
}
echo "<br>";
//pad the message depending on the padding parameter
// if ($padding == 2) $message .= " "; //pad the message with spaces
// else if ($padding == 1) {$temp = chr (8-($len%8)); $message .= $temp . $temp . $temp . $temp . $temp . $temp . $temp . $temp; if ($temp==8) $len+=8;} //PKCS7 padding
// else if (!$padding) $message .= (chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0)); //pad the message out with null bytes
//store the result here
$result = "";
$tempresult = "";
if ($mode == 1) { //CBC mode
$cbcleft = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++});
$cbcright = (ord($iv{$m++}) << 24) | (ord($iv{$m++}) << 16) | (ord($iv{$m++}) << 8) | ord($iv{$m++});
$m=0;
}
echo "mode:".$mode;
echo "<br>";
echo "5.cbcleft:".$cbcleft;
echo "<br>";
echo "6.cbcright:".$cbcright;
echo "<br>";
//loop through each 64 bit chunk of the message
while ($m < $len) {
$left = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++});
$right = (ord($message{$m++}) << 24) | (ord($message{$m++}) << 16) | (ord($message{$m++}) << 8) | ord($message{$m++});
//for Cipher Block Chaining mode, xor the message with the previous result
if ($mode == 1) {if ($encrypt) {$left ^= $cbcleft; $right ^= $cbcright;} else {$cbcleft2 = $cbcleft; $cbcright2 = $cbcright; $cbcleft = $left; $cbcright = $right;}}
//first each 64 but chunk of the message must be permuted according to IP
$temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
$temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16);
$temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2);
$temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
$temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
$left = (($left << 1) | ($left >> 31 & $masks[31]));
$right = (($right << 1) | ($right >> 31 & $masks[31]));
//do this either 1 or 3 times for each chunk of the message
for ($j=0; $j<$iterations; $j+=3) {
$endloop = $looping[$j+1];
$loopinc = $looping[$j+2];
//now go through and perform the encryption or decryption
for ($i=$looping[$j]; $i!=$endloop; $i+=$loopinc) { //for efficiency
$right1 = $right ^ $keys[$i];
$right2 = (($right >> 4 & $masks[4]) | ($right << 28 & 0xffffffff)) ^ $keys[$i+1];
//the result is attained by passing these bytes through the S selection functions
$temp = $left;
$left = $right;
$right = $temp ^ ($spfunction2[($right1 >> 24 & $masks[24]) & 0x3f] | $spfunction4[($right1 >> 16 & $masks[16]) & 0x3f]
| $spfunction6[($right1 >> 8 & $masks[8]) & 0x3f] | $spfunction8[$right1 & 0x3f]
| $spfunction1[($right2 >> 24 & $masks[24]) & 0x3f] | $spfunction3[($right2 >> 16 & $masks[16]) & 0x3f]
| $spfunction5[($right2 >> 8 & $masks[8]) & 0x3f] | $spfunction7[$right2 & 0x3f]);
}
$temp = $left; $left = $right; $right = $temp; //unreverse left and right
} //for either 1 or 3 iterations
//move then each one bit to the right
$left = (($left >> 1 & $masks[1]) | ($left << 31));
$right = (($right >> 1 & $masks[1]) | ($right << 31));
//now perform IP-1, which is IP in the opposite direction
$temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
$temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
$temp = (($right >> 2 & $masks[2]) ^ $left) & 0x33333333; $left ^= $temp; $right ^= ($temp << 2);
$temp = (($left >> 16 & $masks[16]) ^ $right) & 0x0000ffff; $right ^= $temp; $left ^= ($temp << 16);
$temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
//for Cipher Block Chaining mode, xor the message with the previous result
if ($mode == 1) {if ($encrypt) {$cbcleft = $left; $cbcright = $right;} else {$left ^= $cbcleft2; $right ^= $cbcright2;}}
$tempresult .= (chr($left>>24 & $masks[24]) . chr(($left>>16 & $masks[16]) & 0xff) . chr(($left>>8 & $masks[8]) & 0xff) . chr($left & 0xff) . chr($right>>24 & $masks[24]) . chr(($right>>16 & $masks[16]) & 0xff) . chr(($right>>8 & $masks[8]) & 0xff) . chr($right & 0xff));
$chunk += 8;
if ($chunk == 512) {$result .= $tempresult; $tempresult = ""; $chunk = 0;}
} //for every 8 characters, or 64 bits in the message
//return the result as an array
return ($result . $tempresult);
} //end of des
//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys ($key) {
//declaring this locally speeds things up a bit
$pc2bytes0 = array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
$pc2bytes1 = array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
$pc2bytes2 = array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
$pc2bytes3 = array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
$pc2bytes4 = array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
$pc2bytes5 = array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
$pc2bytes6 = array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
$pc2bytes7 = array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
$pc2bytes8 = array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
$pc2bytes9 = array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
$pc2bytes10 = array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
$pc2bytes11 = array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
$pc2bytes12 = array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
$pc2bytes13 = array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
$masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0);
//how many iterations (1 for des, 3 for triple des)
// $iterations = ((strlen($key) > 8) ? 3 : 1); //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
$iterations = ((strlen($key) > 24) ? 3 : 1); //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
//stores the return keys
$keys = array (); // size = 32 * iterations but you don't specify this in php
//now define the left shifts which need to be done
$shifts = array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
//other variables
$m=0;
$n=0;
for ($j=0; $j<$iterations; $j++) { //either 1 or 3 iterations
$left = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});
$right = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});
$temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
$temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << 16);
$temp = (($left >> 2 & $masks[2]) ^ $right) & 0x33333333; $right ^= $temp; $left ^= ($temp << 2);
$temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; $right ^= ($temp << 16);
$temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
$temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
$temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
//the right side needs to be shifted and to get the last four bits of the left side
$temp = ($left << 8) | (($right >> 20 & $masks[20]) & 0x000000f0);
//left needs to be put upside down
$left = ($right << 24) | (($right << 8) & 0xff0000) | (($right >> 8 & $masks[8]) & 0xff00) | (($right >> 24 & $masks[24]) & 0xf0);
$right = $temp;
//now go through and perform these shifts on the left and right keys
for ($i=0; $i < count($shifts); $i++) {
//shift the keys either one or two bits to the left
if ($shifts[$i] > 0) {
$left = (($left << 2) | ($left >> 26 & $masks[26]));
$right = (($right << 2) | ($right >> 26 & $masks[26]));
} else {
$left = (($left << 1) | ($left >> 27 & $masks[27]));
$right = (($right << 1) | ($right >> 27 & $masks[27]));
}
$left = $left & -0xf;
$right = $right & -0xf;
//now apply PC-2, in such a way that E is easier when encrypting or decrypting
//this conversion will look like PC-2 except only the last 6 bits of each byte are used
//rather than 48 consecutive bits and the order of lines will be according to
//how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
$lefttemp = $pc2bytes0[$left >> 28 & $masks[28]] | $pc2bytes1[($left >> 24 & $masks[24]) & 0xf]
| $pc2bytes2[($left >> 20 & $masks[20]) & 0xf] | $pc2bytes3[($left >> 16 & $masks[16]) & 0xf]
| $pc2bytes4[($left >> 12 & $masks[12]) & 0xf] | $pc2bytes5[($left >> 8 & $masks[8]) & 0xf]
| $pc2bytes6[($left >> 4 & $masks[4]) & 0xf];
$righttemp = $pc2bytes7[$right >> 28 & $masks[28]] | $pc2bytes8[($right >> 24 & $masks[24]) & 0xf]
| $pc2bytes9[($right >> 20 & $masks[20]) & 0xf] | $pc2bytes10[($right >> 16 & $masks[16]) & 0xf]
| $pc2bytes11[($right >> 12 & $masks[12]) & 0xf] | $pc2bytes12[($right >> 8 & $masks[8]) & 0xf]
| $pc2bytes13[($right >> 4 & $masks[4]) & 0xf];
$temp = (($righttemp >> 16 & $masks[16]) ^ $lefttemp) & 0x0000ffff;
$keys[$n++] = $lefttemp ^ $temp; $keys[$n++] = $righttemp ^ ($temp << 16);
}
} //for each iterations
//return the keys we've created
for($ii = 0; $ii < count($keys); $ii++){
echo ",".$keys[$ii];
}
echo "<br>";
return $keys;
} //end of des_createKeys
////////////////////////////// TEST //////////////////////////////
function stringToHex ($s) {
$r = "0x";
$hexes = array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
for ($i=0; $i<strlen($s); $i++) {$r .= ($hexes [(ord($s{$i}) >> 4)] . $hexes [(ord($s{$i}) & 0xf)]);}
return $r;
}
function hexToString ($h) {
$r = "";
for ($i= (substr($h, 0, 2)=="0x")?2:0; $i<strlen($h); $i+=2) {$r .= chr (base_convert (substr ($h, $i, 2), 16, 10));}
return $r;
}
function idtag_des_encode($text)
{
$key = '12345678';
$y=pkcs5_pad($text);
echo "y:".$y;
echo "<br />";
$td = mcrypt_mole_open(MCRYPT_DES,'',MCRYPT_MODE_CBC,''); //使用MCRYPT_DES演算法,cbc模式
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$ks = mcrypt_enc_get_key_size($td);
mcrypt_generic_init($td, $key, $key); //初始處理
$encrypted = mcrypt_generic($td, $y); //解密
mcrypt_generic_deinit($td); //結束
mcrypt_mole_close($td);
return $encrypted;
// return base64_encode($encrypted);
}
function pkcs5_pad($text,$block=8)
{
$pad = $block - (strlen($text) % $block);
return $text . str_repeat(chr($pad), $pad);
}
$key = "12345678";
$message = "str4";
$ciphertext = des ($key, $message, 1, 1, $key,null);
//echo "stringToHex (ciphertext): " . stringToHex ($ciphertext);
//echo "<br />";
echo "base64_encode(ciphertext): " . base64_encode($ciphertext);
//echo "<br />";
//echo "encode64(ciphertext): " . encode64($ciphertext);
//echo "<br />";
//echo "base64_encode(stringToHex (ciphertext)): " . base64_encode(stringToHex ($ciphertext));
//echo "<br />";
//echo "stringToHex (base64_encode(ciphertext)): " . stringToHex (idtag_des_encode($message));
echo "<br />";
echo "idtag_des_encode: " .base64_encode(idtag_des_encode($message));
//$recovered_message = des ($key, $ciphertext, 0, 0, null,null);
//echo "\n";
//echo "DES Test Decrypted: " . $recovered_message;
?>