narf/simple-encryption

一个用于PHP下的对称加密的简单库

dev-master 2015-06-03 14:45 UTC

This package is not auto-updated.

Last update: 2024-09-10 02:30:05 UTC


README

一个用于对称加密的PHP库,使加密变得简单、安全且易于访问。

实验性!在1.0版本被打标签之前,请不要使用此库!

Build Status

简介

每个人都有想要进行加密的理由。问题是,很少有人对密码学了解足够,能够正确实现它。这可能看起来很简单,或者微不足道,但请相信我,为了你自己的利益:这绝对不是!

大多数人甚至不知道加密和散列之间的区别,密码学之所以是单独的科学学科,是有很好的原因的。即使是一个好、有经验的甚至杰出的开发者,通常也不够。仅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::PLAINTEXTSecret::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: nullSecret::PLAINTEXTSecret::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实现。库内部使用,公开是因为没有必要不公开。如果您不知道它是做什么的,您不需要它。