加密/解密
最后更新于:2022-04-02 05:15:40
[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
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
encrypt($text, $key);
echo $crypt->decrypt($encrypted, $key);
```
您可以使用相同的实例多次加密/解密:
```php
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
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
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
getAvailableHashAlgos();
var_dump($algorithms);
```
## Base64支持
为了正确传输(电子邮件)或显示(浏览器)加密,[base64](http://www.php.net/manual/en/function.base64-encode.php)编码通常应用于加密文本:
```php
encryptBase64($text, $key);
echo $crypt->decryptBase64($encrypt, $key);
```
## 设置加密服务
您可以在服务容器中设置加密组件,以便从应用程序的任何部分使用它:
```php
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
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)
';