##1.26.1 对称加密和非对称加密
关于数据加密和安全这一块,只作简单说明。
首先,对称加密是指数据可以加密成密文也可以解密还原,共用同一个密钥,而非对称是则公钥和私钥,两者皆使用可逆加密算法。不可逆加密不存在密钥,只有salt,用来增加可变性和随机性,如md5。而在加密里面,又数块算法加密的方式最为完善,随附图一张:
![05152](http://webtools.qiniudn.com/20150411005257_f66cbee3d910a092bfee33dd72a2f3cd)
##1.26.2 PHP的mcrypt加密扩展
在PhalApi中,同样也是使用了mcrypt作为底层的数据加密技术方案。请查看: [PHP 手册 函数参考 加密扩展](http://php.net/manual/zh/book.mcrypt.php)
##1.26.3 加解密的使用
在单元测试中,我们可以快速找到加密和解密的使用,这里再简单举一例:
```javascript
$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);
```
上面将会输出(有乱码):
![0215](http://webtools.qiniudn.com/20150411005257_f8e1f72b08a9520c391295ca428a9ac5)
##1.26.4 更富弹性和便于存储的加密方案
上面看到,mcrypt下的加密在两点不足:
+ 1、有乱码,不能很好地永久化存储;
+ 2、只针对文本字符串的加密,不支持数组等,且无法还原类型;
为此, 我们提供了更富弹性和便于存储的加密方案,即:序列化 + base64 + mcrypt的多重加密方案。
以下是上面的示例-多重加密版:
```javascript
$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);
```
对应的输出(这里使用了文字结果输出,是因为没了乱码):
```javascript
string(44) "rmFMdhvszAkHhOdzwt/APBACk/Mn/SqhV1Ahp1xT0Gk="
string(23) "The Best Day of My Life"
```
##1.26.5 RSA的支持与超长字符串的应对方案
基于项目有使用RSA进行加密和解密的需求,这里特扩展对RSA的支持。同时针对到RSA对字符串长度的限制,提供了分段处理的方案。RSA加密模块的静态类结构UML如下:
![rsa-PhalApi](http://webtools.qiniudn.com/20150411005257_e38fc8af28ac9c382e0e3ef8efbb2b86)
###(1)原生态的通信加密和解密
此部分只是简单地封装了openssl相关函数的操作,可以实现与其他语言和客户端下RSA的加密通信。
唯一需要注意的是,对于 **“私钥加密,公钥解密”** 和 **“公钥加密,私钥解密”** 这两种情况下key的互换和对应问题。不要混淆。
###(2)超长字符串的分段处理
这里重点说明一下超长字符串通信加密的问题。
解决方案主要涉及两点:一是分段的处理,二是中间层转换。分段是指将待加密的字符串分割成允许最大长度117(有用户反馈说是127)内的数组,再各自处理;中间层转换是为了稳定性、通用性和方便落地存储,使用了json和base64的结合编码。
虽然此方案解决了超长字符串的问题,但需要特别指出的是, **不能与其他语言、或者PHP其他框架和客户端进行原生态的RSA通信** 。
我们突破了长度的限制,但失去了通用性。这里罗列一下各个场景和对应的处理方式:
####支持:PhalApi项目A <--> PhalApi项目A
####支持:PhalApi项目A <--> PhalApi项目B,PhalApi项目C,PhalApi项目D,...
####不支持:PhalApi项目 <--> 非PhalApi项目的PHP项目
解决方案:将以下RSA模块相关的代码以包的形式拷贝到需要的PHP项目。
```javascript
.
├── Crypt
│ └── RSA
│ ├── KeyGenerator.php
│ ├── MultiBase.php
│ ├── MultiPri2Pub.php
│ ├── MultiPub2Pri.php
│ ├── Pri2Pub.php
│ └── Pub2Pri.php
└── Crypt.php
```
####不支持:PhalApi项目 <--> 非PHP语言的项目
解决方案:参考PhalApi对RSA超长字符串的处理,同步实现。
####不支持:PhalApi项目 <--> 客户端(iOS/Android/Windows Phone, etc)
解决方案:参考PhalApi对RSA超长字符串的处理,同步实现。
###(3)使用示例:2块2毛2和故事
这是一个有趣的故事,发生在我一个很好的朋友身上。
在去年暑假的时候,有位师妹通过几层关系找到我朋友,想他帮她支付回家的火车票。本着“调试”(调戏)的精神,我朋友爽快地答应了并让她把支付宝帐号发过来。然后,不一会,我朋友收到了一条有支付宝帐号的短信,立马打了2.22元过去,并附言: **别问我是谁,请叫我雷锋!** 后来证实师妹没发来过短信,原来收到的那条是诈骗的短信。。。。你能想象得到骗子收到这2.22元和看到这条留言时的表情么,哈哈~~
以下测试代码,以上面故事为背景,并演示了RSA的使用示例:
```javascript
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);
}
```
##1.26.6 建议
在上面的加密中,接口项目在开发时,需要自定义两个值:加密向量和私钥。
为了提高数据加密的安全度,建议:
+ 加密向量项目统一在./Config/app.php中配置;
+ 各模块业务数据加密所用的Key则由各业务点自定义;
这样,可以对不同的数据使用不同的加密私钥,即使破解了某一个用户的数据,也难以破解其他用户的。
##1.26.7 扩展你的对称加密
尤其对于加密方案和算法,我们在项目开发决策时,更应该优先考虑使用现在行业内成熟公认的加密方案和算法,而不是自己去从头研发。
但如果你项目确实有此需要,或者需要在mcrypt的基础上再作一些变通,也是可以很快地实现和注册使用。
首先,请先实现下面的加密接口:
```javascript
// $vim ./PhalApi/PhalApi/Crypt.php
interface PhalApi_Crypt {
public function encrypt($data, $key);
public function decrypt($data, $key);
}
```
然后,重新注册加密服务即可。
- 欢迎使用PhalApi!
- 接口,从简单开始!
- [1.1]-下载与安装
- [1.2]-创建一个自己的项目
- [1.3]-在线体验
- [1.4]-文档、帮助和官网
- [1.10]-对PhalApi框架的抉择
- [1.11]-快速入门(backup)
- [1.12]-参数规则:接口参数规则配置
- [1.13]-统一的接口请求方式:_sevice=XXX.XXX
- [1.14]-统一的返回格式和结构:ret-data-msg
- [1.15]-数据库操作:基于NotORM的使用及优化
- [1.16]-配置读取:内外网环境配置的完美切换
- [1.17]-日记纪录:简化版的日记接口
- [1.18]-快速函数:人性化的关怀
- [1.19]-DI服务速查:各资源服务一览表
- [1.20]-DB操作:数据库基本操作速查
- [1.21]-类的自动加载:遵循PEAR包的命名规范
- [1.22]-签名验证:自定义签名规则
- [1.23]-请求和响应:GET和POST两者皆可得及超越JSON格式返回
- [1.24]-缓存策略:更灵活地可配置化的多级缓存
- [1.25]-国际化翻译:为走向国际化提前做好翻译准备
- [1.26]-数据安全:数据对称加密方案
- [1.27]-精益开发:更富表现力的Model层和重量级数据获取的应对方案
- [1.28]-COOKIE:对COOKIE原生态的支持及记忆加密升级版
- [1.29]-开放与封闭:多入口和统一初始化
- [1.30]-保持的力量:接口开发最佳实践
- [1.31]-新型计划任务:以接口形式实现的计划任务
- [2.11]-核心思想:DI依赖注入-让资源更可控
- [2.12]-海量数据:可配置的分库分表
- [2.13]-接口调试:在线SQL语句查看与性能优化
- [2.14]-测试驱动开发:意图导向编程下的接口开发
- [2.15]-演进:新型计划任务续篇
- [2.16]-领域驱动设计:应对复杂领域业务的Domain层
- [2.17]-微服务:Api接口服务层
- [2.18]-定制化:资源服务的再实现
- [2.19]-扩展库:可重用的扩展类库
- [2.20]-约定编程:架构明显的编程风格
- [2.21]-服务器统一部署方案简明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益项目和团队建设
- [3.1]-扩展类库:微信开发
- [3.2]-扩展类库:代理模式下phprpc协议的轻松支持
- [3.3]-扩展类库:基于PHPMailer的邮件发送
- [3.4]-扩展类库:优酷开放平台接口调用
- [3.5]-扩展类库:七牛云存储接口调用
- [3.6]-扩展类库:新型计划任务
- [3.8]-扩展类库:用户、会话和第三方登录集成
- [3.9]-扩展类库:swoole支持下的长链接和异步任务实现
- [3.11]-扩展类库:基于FastRoute的快速路由
- [4.2]-开发实战2:模拟优酷开放平台接口项目开发
- [4.3]-开发实战3:一个简单的小型项目开发(奔跑吧兄弟投票活动)
- [5.1]-架构与思想:PhalApi核心设计和思想解读
- [5.2]-杂谈:扯一些PhalApi的前世和今生
- [5.3]-框架总结:术语表和PHP开发建议
- [5.4]-许可
- [5.5]-联系和加入我们
- [5.6]-更新日记
- [5.8]-致框架贡献者:加入PhalApi开源指南
- [6.1]-基于接口查询语言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi视频教程
- 附录1:接口文档参考模板