W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
關(guān)于數(shù)據(jù)加密和安全這一塊,只作簡(jiǎn)單說(shuō)明。
首先,對(duì)稱加密是指數(shù)據(jù)可以加密成密文也可以解密還原,共用同一個(gè)密鑰,而非對(duì)稱是則公鑰和私鑰,兩者皆使用可逆加密算法。不可逆加密不存在密鑰,只有salt,用來(lái)增加可變性和隨機(jī)性,如md5。而在加密里面,又?jǐn)?shù)塊算法加密的方式最為完善,隨附圖一張:
在PhalApi中,同樣也是使用了mcrypt作為底層的數(shù)據(jù)加密技術(shù)方案。請(qǐng)查看: PHP 手冊(cè) 函數(shù)參考 加密擴(kuò)展
在單元測(cè)試中,我們可以快速找到加密和解密的使用,這里再簡(jiǎn)單舉一例:
$mcrypt = new PhalApi_Crypt_Mcrypt('12345678');
$data = 'The Best Day of My Life';
$key = 'phalapi';
$encryptData = $mcrypt->encrypt($data, $key);
var_dump($encryptData);
$decryptData = $mcrypt->decrypt($encryptData, $key);
var_dump($decryptData);
上面將會(huì)輸出(有亂碼):
上面看到,mcrypt下的加密在兩點(diǎn)不足:
為此, 我們提供了更富彈性和便于存儲(chǔ)的加密方案,即:序列化 + base64 + mcrypt的多重加密方案。
以下是上面的示例-多重加密版:
$mcrypt = new PhalApi_Crypt_MultiMcrypt('12345678');
$data = 'The Best Day of My Life';
$key = 'phalapi';
$encryptData = $mcrypt->encrypt($data, $key);
var_dump($encryptData);
$decryptData = $mcrypt->decrypt($encryptData, $key);
var_dump($decryptData);
對(duì)應(yīng)的輸出(這里使用了文字結(jié)果輸出,是因?yàn)闆](méi)了亂碼):
string(44) "rmFMdhvszAkHhOdzwt/APBACk/Mn/SqhV1Ahp1xT0Gk="
string(23) "The Best Day of My Life"
基于項(xiàng)目有使用RSA進(jìn)行加密和解密的需求,這里特?cái)U(kuò)展對(duì)RSA的支持。同時(shí)針對(duì)到RSA對(duì)字符串長(zhǎng)度的限制,提供了分段處理的方案。RSA加密模塊的靜態(tài)類結(jié)構(gòu)UML如下:
此部分只是簡(jiǎn)單地封裝了openssl相關(guān)函數(shù)的操作,可以實(shí)現(xiàn)與其他語(yǔ)言和客戶端下RSA的加密通信。
唯一需要注意的是,對(duì)于 “私鑰加密,公鑰解密” 和 “公鑰加密,私鑰解密” 這兩種情況下key的互換和對(duì)應(yīng)問(wèn)題。不要混淆。
這里重點(diǎn)說(shuō)明一下超長(zhǎng)字符串通信加密的問(wèn)題。
解決方案主要涉及兩點(diǎn):一是分段的處理,二是中間層轉(zhuǎn)換。分段是指將待加密的字符串分割成允許最大長(zhǎng)度117(有用戶反饋說(shuō)是127)內(nèi)的數(shù)組,再各自處理;中間層轉(zhuǎn)換是為了穩(wěn)定性、通用性和方便落地存儲(chǔ),使用了json和base64的結(jié)合編碼。
雖然此方案解決了超長(zhǎng)字符串的問(wèn)題,但需要特別指出的是, 不能與其他語(yǔ)言、或者PHP其他框架和客戶端進(jìn)行原生態(tài)的RSA通信 。
我們突破了長(zhǎng)度的限制,但失去了通用性。這里羅列一下各個(gè)場(chǎng)景和對(duì)應(yīng)的處理方式:
解決方案:將以下RSA模塊相關(guān)的代碼以包的形式拷貝到需要的PHP項(xiàng)目。
.
├── Crypt
│ └── RSA
│ ├── KeyGenerator.php
│ ├── MultiBase.php
│ ├── MultiPri2Pub.php
│ ├── MultiPub2Pri.php
│ ├── Pri2Pub.php
│ └── Pub2Pri.php
└── Crypt.php
解決方案:參考PhalApi對(duì)RSA超長(zhǎng)字符串的處理,同步實(shí)現(xiàn)。
解決方案:參考PhalApi對(duì)RSA超長(zhǎng)字符串的處理,同步實(shí)現(xiàn)。
這是一個(gè)有趣的故事,發(fā)生在我一個(gè)很好的朋友身上。
在去年暑假的時(shí)候,有位師妹通過(guò)幾層關(guān)系找到我朋友,想他幫她支付回家的火車票。本著“調(diào)試”(調(diào)戲)的精神,我朋友爽快地答應(yīng)了并讓她把支付寶帳號(hào)發(fā)過(guò)來(lái)。然后,不一會(huì),我朋友收到了一條有支付寶帳號(hào)的短信,立馬打了2.22元過(guò)去,并附言: 別問(wèn)我是誰(shuí),請(qǐng)叫我雷鋒! 后來(lái)證實(shí)師妹沒(méi)發(fā)來(lái)過(guò)短信,原來(lái)收到的那條是詐騙的短信。。。。你能想象得到騙子收到這2.22元和看到這條留言時(shí)的表情么,哈哈~~
以下測(cè)試代碼,以上面故事為背景,并演示了RSA的使用示例:
public function testDecryptAfterEncrypt()
{
$keyG = new PhalApi_Crypt_RSA_KeyGenerator();
$privkey = $keyG->getPriKey();
$pubkey = $keyG->getPubKey();
DI()->crypt = new PhalApi_Crypt_RSA_MultiPri2Pub();
$data = 'AHA! I have $2.22 dollars!';
$encryptData = DI()->crypt->encrypt($data, $privkey);
$decryptData = DI()->crypt->decrypt($encryptData, $pubkey);
$this->assertEquals($data, $decryptData);
}
在上面的加密中,接口項(xiàng)目在開(kāi)發(fā)時(shí),需要自定義兩個(gè)值:加密向量和私鑰。
為了提高數(shù)據(jù)加密的安全度,建議:
這樣,可以對(duì)不同的數(shù)據(jù)使用不同的加密私鑰,即使破解了某一個(gè)用戶的數(shù)據(jù),也難以破解其他用戶的。
尤其對(duì)于加密方案和算法,我們?cè)陧?xiàng)目開(kāi)發(fā)決策時(shí),更應(yīng)該優(yōu)先考慮使用現(xiàn)在行業(yè)內(nèi)成熟公認(rèn)的加密方案和算法,而不是自己去從頭研發(fā)。
但如果你項(xiàng)目確實(shí)有此需要,或者需要在mcrypt的基礎(chǔ)上再作一些變通,也是可以很快地實(shí)現(xiàn)和注冊(cè)使用。
首先,請(qǐng)先實(shí)現(xiàn)下面的加密接口:
// $vim ./PhalApi/PhalApi/Crypt.php
interface PhalApi_Crypt {
public function encrypt($data, $key);
public function decrypt($data, $key);
}
然后,重新注冊(cè)加密服務(wù)即可。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: