[TOC]
# 加密/解密
Phalcon通过`Phalcon\Crypt`组件提供加密功能。该类为[openssl](http://www.php.net/manual/en/book.openssl.php) PHP的加密库提供了简单的面向对象的包装器。
默认情况下,此组件使用AES-256-CFB提供安全加密。
密码AES-256用于Internet上的SSL/TLS中的其他位置。它被认为是顶级密码之一。理论上它是不可破解的,因为密钥的组合是巨大的。尽管NSA已将此分类在[Suite B](https://en.wikipedia.org/wiki/NSA_Suite_B_Cryptography)中,但他们还建议使用高于128位的密钥进行加密。
>[warning] 您必须使用与当前算法相对应的密钥长度。对于默认使用的算法,它是32个字节。
如果在对象构造期间未选择用于计算摘要(签名)的算法,则默认选择aes-256-cfb。
## 基础使用
该组件设计非常简单易用:
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt();
/**
* Set the cipher algorithm.
*
* The `aes-256-gcm' is the preferable cipher, but it is not usable until the
* openssl library is upgraded, which is available in PHP 7.1.
*
* The `aes-256-ctr' is arguably the best choice for cipher
* algorithm in these days.
*/
$crypt->setCipher('aes-256-ctr');
/**
* Set the encryption key.
*
* The `$key' should have been previously generated in a cryptographically safe way.
*
* Bad key:
* "le password"
*
* Better (but still unsafe):
* "#1dj8$=dp?.ak//j1V$~%*0X"
*
* Good key:
* "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
*
* Use your own key. Do not copy and paste this example key.
*/
$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'This is the text that you want to encrypt.';
$encrypted = $crypt->encrypt($text, $key);
echo $crypt->decrypt($encrypted, $key);
```
您还可以设置算法以及在对象构造期间是否计算消息的摘要(签名)。这消除了调用`setCipher()`和`useSigning()`的需要:
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt('aes-256-ctr', true);
$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'This is the text that you want to encrypt.';
$encrypted = $crypt->encrypt($text, $key);
echo $crypt->decrypt($encrypted, $key);
```
您可以使用相同的实例多次加密/解密:
```php
<?php
use Phalcon\Crypt;
$crypt->setCipher('aes-256-ctr');
// Create an instance
$crypt = new Crypt();
// Use your own keys!
$texts = [
"T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c" => 'This is a secret text',
"T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3" => 'This is a very secret',
];
foreach ($texts as $key => $text) {
// Perform the encryption
$encrypted = $crypt->encrypt($text, $key);
// Now decrypt
echo $crypt->decrypt($encrypted, $key);
}
```
为了更好的安全性,您可以指示组件根据 `getAvailableHashAlgos` 返回的受支持算法之一计算消息摘要。如上所示,该算法可以在对象实例化期间设置,但也可以在之后设置。
**注意** 默认情况下,Phalcon 4.0.0或更高版本将启用计算消息摘要(签名)。
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt();
$crypt->setCipher('aes-256-ctr');
$crypt->setHashAlgo('aes-256-cfb');
// Force calculation of a digest of the message based on the Hash algorithm
$crypt->useSigning(true);
$key = "T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c";
$text = 'This is a secret text';
// Perform the encryption
$encrypted = $crypt->encrypt($text, $key);
// Now decrypt
echo $crypt->decrypt($encrypted, $key);
```
## 加密选项
以下选项可用于更改加密行为:
| 名称 | 描述 |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Cipher | 密码是openssl支持的加密算法之一。你可以在[这里](http://www.php.net/manual/en/function.openssl-get-cipher-methods.php)看到一个列表|
案例:
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt();
// Use blowfish
$crypt->setCipher('bf-cbc');
// Use your own key!
$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'This is a secret text';
echo $crypt->encrypt($text, $key);
```
如果要检查系统支持的可用算法,可以调用 `getAvailableHashAlgos()` 方法。
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt();
// Get the supported algorithms
$algorithms = $crypt->getAvailableHashAlgos();
var_dump($algorithms);
```
## Base64支持
为了正确传输(电子邮件)或显示(浏览器)加密,[base64](http://www.php.net/manual/en/function.base64-encode.php)编码通常应用于加密文本:
```php
<?php
use Phalcon\Crypt;
// Create an instance
$crypt = new Crypt();
// Use your own key!
$key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
$text = 'This is a secret text';
$encrypt = $crypt->encryptBase64($text, $key);
echo $crypt->decryptBase64($encrypt, $key);
```
## 设置加密服务
您可以在服务容器中设置加密组件,以便从应用程序的任何部分使用它:
```php
<?php
use Phalcon\Crypt;
$di->set(
'crypt',
function () {
$crypt = new Crypt();
// Set a global encryption key
$crypt->setKey(
"T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
);
return $crypt;
},
true
);
```
然后,例如,在控制器中,您可以按如下方式使用它:
```php
<?php
use Phalcon\Mvc\Controller;
class SecretsController extends Controller
{
public function saveAction()
{
$secret = new Secrets();
$text = $this->request->getPost('text');
$secret->content = $this->crypt->encrypt($text);
if ($secret->save()) {
$this->flash->success(
'Secret was successfully created!'
);
}
}
}
```
## 链接
* [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
* [What is block cipher](https://en.wikipedia.org/wiki/Block_cipher)
* [Introduction to Blowfish](http://www.splashdata.com/splashid/blowfish.htm)
* [CTR-Mode Encryption](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.79.1353&rep=rep1&type=pdf)
* [Recommendation for Block Cipher Modes of Operation: Methods and Techniques](https://csrc.nist.gov/publications/detail/sp/800-38a/final)
* [Counter (CTR) mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29)
- 常规
- Welcome
- 贡献
- 生成回溯
- 测试重现
- 单元测试
- 入门
- 安装
- Web服务器设置
- WAMP
- XAMPP
- 教程
- 基础教程
- 教程:创建一个简单的REST API
- 教程:Vökuró
- 提升性能
- 教程:INVO
- 开发环境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 开发工具
- Phalcon开发者工具的安装
- Phalcon开发者工具的使用
- 调试应用程序
- 核心
- MVC应用
- 微应用
- 创建命令行(CLI)应用程序
- 依赖注入与服务定位
- MVC架构
- 服务
- 使用缓存提高性能
- 读取配置
- 上下文转义
- 类加载器
- 使用命名空间
- 日志
- 队列
- 数据库
- 数据库抽象层
- Phalcon查询语言(PHQL)
- ODM(对象文档映射器)
- 使用模型
- 模型行为
- ORM缓存
- 模型事件
- 模型元数据
- 模型关系
- 模型事务
- 验证模型
- 数据库迁移
- 分页
- 前端
- Assets管理
- 闪存消息
- 表单
- 图像
- 视图助手(标签)
- 使用视图
- Volt:模板引擎
- 业务逻辑
- 访问控制列表(ACL)
- 注解解析器
- 控制器
- 调度控制器
- 事件管理器
- 过滤与清理
- 路由
- 在session中存储数据
- 生成URL和路径
- 验证
- HTTP
- Cookies管理
- 请求环境
- 返回响应
- 安全
- 加密/解密
- 安全
- 国际化
- 国际化
- 多语言支持