×
PhalApi 2.x 前言

PhalApi 2.x 快速开发

1.1 下载与安装1.2 运行Hello World1.3 如何请求接口服务1.4 接口响应与在线调试1.5 Api接口层1.6 Domain领域层和ADM模式1.7 Model数据层与数据库操作1.8 单元测试1.9 自动加载和PSR-41.10 接口文档

PhalApi 2.x 数据库

2.1 数据库链接2.2 数据库与NotORM2.3 数据库使用和查询2.4 数据库分库分表策略2.5 连接多个数据库2.6 打印和保存SQL语句2.7 定制你的Model基类

PhalApi 2.x 高级专题

3.1 PhalApi 2.x 接口参数3.2 PhalApi 2.x 配置3.3 PhalApi 2.x 日志3.4 PhalApi 2.x 缓存3.5 PhalApi 2.x 过滤器3.6 PhalApi 2.x COOKIE3.7 PhalApi 2.x 加密3.8 PhalApi 2.x 国际化3.9 PhalApi 2.x CURL请求3.10 PhalApi 2.x 工具和杂项3.11 PhalApi 2.x DI服务汇总

PhalApi 2.x 发现更多

4.1 PhalApi 2.x 扩展类库4.2 PhalApi 2.x SDK包的使用4.3 PhalApi 2.x 脚本命令

关于PhalApi 2.x

5.1 PhalApi 2.x 版本完美诠释5.2 PhalApi 2.x 升级指南5.3 PhalApi 2.x VS PhalApi 1.x

3.7 PhalApi 2.x 加密


PHP的mcrypt加密扩展

在PhalApi中,同样也是使用了mcrypt作为底层的数据加密技术方案。请查看:PHP 手册 函数参考 加密扩展

不过需要注意的是,在PHP7中,将废弃此扩展。

加解密的使用

在单元测试中,我们可以快速找到加密和解密的使用,这里再简单举一例:

$mcrypt = new PhalApiCryptMcryptCrypt('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);

上面将会输出(有乱码):

0215

更富弹性和便于存储的加密方案

上面看到,mcrypt下的加密在两点不足:

  • 1、有乱码,不能很好地永久化存储;
  • 2、只针对文本字符串的加密,不支持数组等,且无法还原类型;

为此, 我们提供了更富弹性和便于存储的加密方案,即:序列化 + base64 + mcrypt的多重加密方案。

以下是上面的示例-多重加密版:

$mcrypt = new PhalApiCryptMultiMcryptCrypt('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);

对应的输出(这里使用了文字结果输出,是因为没了乱码):

string(44) "rmFMdhvszAkHhOdzwt/APBACk/Mn/SqhV1Ahp1xT0Gk="
string(23) "The Best Day of My Life"

RSA的支持与超长字符串的应对方案

基于项目有使用RSA进行加密和解密的需求,这里特扩展对RSA的支持。同时针对到RSA对字符串长度的限制,提供了分段处理的方案。RSA加密模块的静态类结构UML如下:
rsa-PhalApi

原生态的通信加密和解密

此部分只是简单地封装了openssl相关函数的操作,可以实现与其他语言和客户端下RSA的加密通信。
唯一需要注意的是,对于 “私钥加密,公钥解密”“公钥加密,私钥解密” 这两种情况下key的互换和对应问题。不要混淆。

超长字符串的分段处理

这里重点说明一下超长字符串通信加密的问题。
解决方案主要涉及两点:一是分段的处理,二是中间层转换。分段是指将待加密的字符串分割成允许最大长度117(有用户反馈说是127)内的数组,再各自处理;中间层转换是为了稳定性、通用性和方便落地存储,使用了json和base64的结合编码。

虽然此方案解决了超长字符串的问题,但需要特别指出的是, 不能与其他语言、或者PHP其他框架和客户端进行原生态的RSA通信
我们突破了长度的限制,但失去了通用性。这里罗列一下各个场景和对应的处理方式:

  • 支持:PhalApi项目A <--> PhalApi项目A
  • 支持:PhalApi项目A <--> PhalApi项目B,PhalApi项目C,PhalApi项目D,...
  • 不支持:PhalApi项目 <--> 非PhalApi项目的PHP项目
  • 不支持:PhalApi项目 <--> 非PHP语言的项目。
    解决方案:参考PhalApi对RSA超长字符串的处理,同步实现。
  • 不支持:PhalApi项目 <--> 客户端(iOS/Android/Windows Phone, etc)。
    解决方案:参考PhalApi对RSA超长字符串的处理,同步实现。

使用示例

以下是单元测试中的使用示例。

    public function testDecryptAfterEncrypt()
    {
        $keyG = new PhalApiCryptRSAKeyGenerator();
        $privkey = $keyG->getPriKey();
        $pubkey = $keyG->getPubKey();

        PhalApiDI()->crypt = new PhalApiCryptRSAMultiPri2PubCrypt();

        $data = 'AHA! I have $2.22 dollars!';

        $encryptData = DI()->crypt->encrypt($data, $privkey);

        $decryptData = DI()->crypt->decrypt($encryptData, $pubkey);

        $this->assertEquals($data, $decryptData);
    }

建议

在上面的加密中,接口项目在开发时,需要自定义两个值:加密向量和私钥。

为了提高数据加密的安全度,建议:

  • 加密向量项目统一在./Config/app.php中配置;
  • 各模块业务数据加密所用的Key则由各业务点自定义;

这样,可以对不同的数据使用不同的加密私钥,即使破解了某一个用户的数据,也难以破解其他用户的。

扩展:实现你的加密方式

尤其对于加密方案和算法,我们在项目开发决策时,更应该优先考虑使用现在行业内成熟公认的加密方案和算法,而不是自己去从头研发。

但如果你项目确实有此需要,或者需要在mcrypt的基础上再作一些变通,也是可以很快地实现和注册使用。

首先,请先实现下面的加密接口:

<?php
namespace PhalApi;

interface Crypt {

    public function encrypt($data, $key);

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

然后,重新注册加密服务即可。


分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)