在PhalApi中,同樣也是使用了mcrypt作為底層的數(shù)據(jù)加密技術方案。請查看:PHP 手冊 函數(shù)參考 加密擴展。
不過需要注意的是,在PHP7中,將廢棄此擴展。
在單元測試中,我們可以快速找到加密和解密的使用,這里再簡單舉一例:
$mcrypt = new PhalApi\Crypt\McryptCrypt('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);
上面將會輸出(有亂碼):
上面看到,mcrypt下的加密在兩點不足:
2、只針對文本字符串的加密,不支持數(shù)組等,且無法還原類型;
為此, 我們提供了更富彈性和便于存儲的加密方案,即:序列化 + base64 + mcrypt的多重加密方案。
以下是上面的示例-多重加密版:
$mcrypt = new PhalApi\Crypt\MultiMcryptCrypt('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);
對應的輸出(這里使用了文字結果輸出,是因為沒了亂碼):
```php
string(44) "rmFMdhvszAkHhOdzwt/APBACk/Mn/SqhV1Ahp1xT0Gk="
string(23) "The Best Day of My Life"
基于項目有使用RSA進行加密和解密的需求,這里特擴展對RSA的支持。同時針對到RSA對字符串長度的限制,提供了分段處理的方案。RSA加密模塊的靜態(tài)類結構UML如下:
此部分只是簡單地封裝了openssl相關函數(shù)的操作,可以實現(xiàn)與其他語言和客戶端下RSA的加密通信。
唯一需要注意的是,對于 “私鑰加密,公鑰解密” 和 “公鑰加密,私鑰解密” 這兩種情況下key的互換和對應問題。不要混淆。
這里重點說明一下超長字符串通信加密的問題。
解決方案主要涉及兩點:一是分段的處理,二是中間層轉換。分段是指將待加密的字符串分割成允許最大長度117(有用戶反饋說是127)內的數(shù)組,再各自處理;中間層轉換是為了穩(wěn)定性、通用性和方便落地存儲,使用了json和base64的結合編碼。
雖然此方案解決了超長字符串的問題,但需要特別指出的是, 不能與其他語言、或者PHP其他框架和客戶端進行原生態(tài)的RSA通信 。
我們突破了長度的限制,但失去了通用性。這里羅列一下各個場景和對應的處理方式:
以下是單元測試中的使用示例。
public function testDecryptAfterEncrypt()
{
$keyG = new PhalApi\Crypt\RSA\KeyGenerator();
$privkey = $keyG->getPriKey();
$pubkey = $keyG->getPubKey();
\PhalApi\DI()->crypt = new PhalApi\Crypt\RSA\MultiPri2PubCrypt();
$data = 'AHA! I have $2.22 dollars!';
$encryptData = DI()->crypt->encrypt($data, $privkey);
$decryptData = DI()->crypt->decrypt($encryptData, $pubkey);
$this->assertEquals($data, $decryptData);
}
在上面的加密中,接口項目在開發(fā)時,需要自定義兩個值:加密向量和私鑰。
為了提高數(shù)據(jù)加密的安全度,建議:
各模塊業(yè)務數(shù)據(jù)加密所用的Key則由各業(yè)務點自定義;
這樣,可以對不同的數(shù)據(jù)使用不同的加密私鑰,即使破解了某一個用戶的數(shù)據(jù),也難以破解其他用戶的。
尤其對于加密方案和算法,我們在項目開發(fā)決策時,更應該優(yōu)先考慮使用現(xiàn)在行業(yè)內成熟公認的加密方案和算法,而不是自己去從頭研發(fā)。
但如果你項目確實有此需要,或者需要在mcrypt的基礎上再作一些變通,也是可以很快地實現(xiàn)和注冊使用。
首先,請先實現(xiàn)下面的加密接口:
<?php
namespace PhalApi;
interface Crypt {
public function encrypt($data, $key);
public function decrypt($data, $key);
}
然后,重新注冊加密服務即可。
更多建議: