2.6 PhalApi 2.x 加密

2018-07-28 21:24 更新

加密

PHP的mcrypt加密擴(kuò)展

在PhalApi中,同樣也是使用了mcrypt作為底層的數(shù)據(jù)加密技術(shù)方案。請(qǐng)查看:PHP 手冊(cè) 函數(shù)參考 加密擴(kuò)展。

不過需要注意的是,在PHP7中,將廢棄此擴(kuò)展。

加解密的使用

在單元測(cè)試中,我們可以快速找到加密和解密的使用,這里再簡(jiǎn)單舉一例:

$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);

上面將會(huì)輸出(有亂碼):

0215

更富彈性和便于存儲(chǔ)的加密方案

上面看到,mcrypt下的加密在兩點(diǎn)不足:

  • 1、有亂碼,不能很好地永久化存儲(chǔ);
  • 2、只針對(duì)文本字符串的加密,不支持?jǐn)?shù)組等,且無法還原類型;

    為此, 我們提供了更富彈性和便于存儲(chǔ)的加密方案,即:序列化 + 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);



對(duì)應(yīng)的輸出(這里使用了文字結(jié)果輸出,是因?yàn)闆]了亂碼):
```php
string(44) "rmFMdhvszAkHhOdzwt/APBACk/Mn/SqhV1Ahp1xT0Gk="
string(23) "The Best Day of My Life"

RSA的支持與超長(zhǎng)字符串的應(yīng)對(duì)方案

基于項(xiàng)目有使用RSA進(jìn)行加密和解密的需求,這里特?cái)U(kuò)展對(duì)RSA的支持。同時(shí)針對(duì)到RSA對(duì)字符串長(zhǎng)度的限制,提供了分段處理的方案。RSA加密模塊的靜態(tài)類結(jié)構(gòu)UML如下:
rsa-PhalApi

原生態(tài)的通信加密和解密

此部分只是簡(jiǎn)單地封裝了openssl相關(guān)函數(shù)的操作,可以實(shí)現(xiàn)與其他語言和客戶端下RSA的加密通信。
唯一需要注意的是,對(duì)于 “私鑰加密,公鑰解密”“公鑰加密,私鑰解密” 這兩種情況下key的互換和對(duì)應(yīng)問題。不要混淆。

超長(zhǎng)字符串的分段處理

這里重點(diǎn)說明一下超長(zhǎng)字符串通信加密的問題。
解決方案主要涉及兩點(diǎn):一是分段的處理,二是中間層轉(zhuǎn)換。分段是指將待加密的字符串分割成允許最大長(zhǎng)度117(有用戶反饋說是127)內(nèi)的數(shù)組,再各自處理;中間層轉(zhuǎn)換是為了穩(wěn)定性、通用性和方便落地存儲(chǔ),使用了json和base64的結(jié)合編碼。

雖然此方案解決了超長(zhǎng)字符串的問題,但需要特別指出的是, 不能與其他語言、或者PHP其他框架和客戶端進(jìn)行原生態(tài)的RSA通信 。
我們突破了長(zhǎng)度的限制,但失去了通用性。這里羅列一下各個(gè)場(chǎng)景和對(duì)應(yīng)的處理方式:

  • 支持:PhalApi項(xiàng)目A <--> PhalApi項(xiàng)目A
  • 支持:PhalApi項(xiàng)目A <--> PhalApi項(xiàng)目B,PhalApi項(xiàng)目C,PhalApi項(xiàng)目D,...
  • 不支持:PhalApi項(xiàng)目 <--> 非PhalApi項(xiàng)目的PHP項(xiàng)目
  • 不支持:PhalApi項(xiàng)目 <--> 非PHP語言的項(xiàng)目。
    解決方案:參考PhalApi對(duì)RSA超長(zhǎng)字符串的處理,同步實(shí)現(xiàn)。
  • 不支持:PhalApi項(xiàng)目 <--> 客戶端(iOS/Android/Windows Phone, etc)。
    解決方案:參考PhalApi對(duì)RSA超長(zhǎng)字符串的處理,同步實(shí)現(xiàn)。

使用示例

以下是單元測(cè)試中的使用示例。

    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);
    }

建議

在上面的加密中,接口項(xiàng)目在開發(fā)時(shí),需要自定義兩個(gè)值:加密向量和私鑰。

為了提高數(shù)據(jù)加密的安全度,建議:

  • 加密向量項(xiàng)目統(tǒng)一在./Config/app.php中配置;
  • 各模塊業(yè)務(wù)數(shù)據(jù)加密所用的Key則由各業(yè)務(wù)點(diǎn)自定義;

    這樣,可以對(duì)不同的數(shù)據(jù)使用不同的加密私鑰,即使破解了某一個(gè)用戶的數(shù)據(jù),也難以破解其他用戶的。

擴(kuò)展:實(shí)現(xiàn)你的加密方式

尤其對(duì)于加密方案和算法,我們?cè)陧?xiàng)目開發(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)下面的加密接口:

<?php
namespace PhalApi;


interface Crypt {


    public function encrypt($data, $key);


    public function decrypt($data, $key);
}

然后,重新注冊(cè)加密服務(wù)即可。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)