narf / simple-encryption
一个用于PHP下的对称加密的简单库
Requires
- php: >= 5.4
- ext-openssl: *
This package is not auto-updated.
Last update: 2024-09-10 02:30:05 UTC
README
一个用于对称加密的PHP库,使加密变得简单、安全且易于访问。
实验性!在1.0版本被打标签之前,请不要使用此库!
简介
每个人都有想要进行加密的理由。问题是,很少有人对密码学了解足够,能够正确实现它。这可能看起来很简单,或者微不足道,但请相信我,为了你自己的利益:这绝对不是!
大多数人甚至不知道加密和散列之间的区别,密码学之所以是单独的科学学科,是有很好的原因的。即使是一个好、有经验的甚至杰出的开发者,通常也不够。仅MCrypt就不够。
这就是为什么密码学专家会告诉你永远不要编写自己的加密代码,而应该始终使用经过良好验证、经过时间考验的库,这些库会 为你做出所有选择。一开始可能听起来不好,但事实上,这是真的。
有很多选择要做出,尤其是很多错误的选择,你可能甚至没有意识到它们,更不用说有资格做出这些选择了。
在PHP的世界里,还有一个相当大的问题——很少有几个密码学库能够做到完全正确 (还有更多不正确),而且我从未见过一个容易使用的库。
即使是好的库,也很容易出错。
SimpleEncryption 尝试解决所有这些问题。
注意:该库已经覆盖了单元测试,但尚未经过审计。我希望开源社区中的密码学专家会做后者。
技术细节
如果你必须知道,这是 SimpleEncryption 所使用的
- 加密使用 AES-256-CTR(是的,IV总是随机的)
- 认证使用 HMAC SHA-256(先加密,然后HMAC;安全免受时间攻击)
- 密钥派生使用 HKDF(一个密钥用于加密,一个用于认证)
要求
- PHP 5.4
- OpenSSL 扩展
安装和加载
待办:一旦发布,将链接到下载和Packagist。
然后,当然,你需要在你的代码中链接到库,无论是通过使用 PSR-4-兼容的自动加载器,还是手动,如下所示
require_once('path/to/SimpleEncryption/src/Secret.php');
最后,将其导入到自己的命名空间
use \Narf\SimpleEncryption\Secret;
用法
加密数据
你只需要创建一个包含你的机密数据的 Secret
对象,然后调用其 getCipherText()
方法。库将自动创建一个加密密钥,你可以通过 getKey()
方法获取。
$mySecret = new Secret('My secret message!');
$encryptedData = $mySecret->getCipherText();
$key = $mySecret->getKey();
解密数据
解密数据同样简单,只需创建一个包含之前加密数据和加密密钥的 Secret
对象,然后调用 getPlainText()
方法进行实际解密。
$mySecret = new Secret($encryptedData, $key);
echo $mySecret->getPlainText();
创建和使用自己的密钥
虽然为每条加密数据使用不同的加密密钥始终是安全的做法,但这并不总是实用的。因此,有时在加密数据之前,你需要将密钥传递给 Secret
类。
然而,在展示如何实际使用您自己的密钥之前,重要的是要注意,加密密钥绝对不能只是一个密码,也不能是散列函数的输出。它绝对不能是任何可读的标准ASCII字符。如果您需要创建自己的密钥,请使用Secret::getRandomBytes()
方法
$yourKey = Secret::getRandomBytes(32);
(长度必须是32字节,或十六进制编码时为64字节,但库无论如何都不会允许您传递不同大小的密钥)
现在,在您拥有一个密钥之后,为了使用它加密数据,您必须在使用之前将其传递给Secret
类。
然而,由于创建带有密钥的Secret
对象通常意味着您提供的是已经加密的数据,因此您必须手动告诉它输入类型。
这通过传递Secret::PLAINTEXT
或Secret::ENCRYPTED
之一作为第三个参数来完成
$yourSecret = new Secret('Your secret message', $yourKey, Secret::PLAINTEXT);
$encryptedData = $yourSecret->getCipherText();
为了方便起见,Secret::ENCRYPTED
也可以接受,尽管它不是功能必需的
$yourSecret = new Secret($encryptedData, $yourKey, Secret::ENCRYPTED);
$plaintextData = $yourSecret->getPlainText();
错误处理
在出现错误的情况下,例如缺少CSPRNG源或身份验证失败,Secret类将抛出RuntimeException
。
因此,为了避免敏感数据泄露,您需要捕获此类异常
try
{
$secret = new Secret($encryptedData, $encryptionKey);
$plainText = $secret->getCipherText();
}
catch (\RuntimeException $e)
{
// Handle the error
}
类参考
-
void __construct($inputText[, $masterKey = null[, $inputType = null]])
$inputText: 输入数据
$masterKey: 十六进制编码的加密密钥
$inputType:null
、Secret::PLAINTEXT
或Secret::ENCRYPTED
之一如果未提供
$inputType
,则提供加密密钥意味着$inputText
是加密数据,反之亦然,不提供密钥意味着$inputText
是明文。 -
string getCipherText()
重新加密并返回数据,如果需要,生成密钥。
-
string getPlainText()
如果需要,解密并返回秘密数据的明文版本。
-
string getKey()
返回十六进制编码的加密密钥,无论它是预先设置的还是新生成的。
-
string static getRandomBytes($length[, $rawOutput = false])
$length: 输出长度(二进制大小)$rawOutput: 是否返回原始二进制数据或十六进制编码的字符串返回随机生成的字节流,适用于创建加密密钥。
-
string static hkdf($key, $digest[, $length = null[, info = ''[, $salt = null]]])
$key: 输入密钥材料(二进制)
$digest: HMAC摘要(算法)
$length: 输出长度
$info: 应用程序/上下文特定信息
$salt: 盐这是一个与RFC 5869兼容的HKDF实现。库内部使用,公开是因为没有必要不公开。如果您不知道它是做什么的,您不需要它。