PHP中的加密

Updating my user management system has been on my to-do list for a long time. One of the main reasons is the encryption system. I created the current version years ago with PHP 5.5. At that point, using mcrypt was recommended on the internet. However, since then mcrypt has become deprecated and has been removed in PHP 7.2. Because the encryption is essential to the system and very hard to change after the fact, I spend a few hours reading up on the current best practices for symmetric encryption in PHP and ended up with AES 256 GCM.

长期以来,更新用户管理系统一直是我的工作清单。 主要原因之一是加密系统。 我几年前使用PHP 5.5创建了当前版本。 那时,建议在Internet上使用mcrypt。 但是,从那时起,mcrypt就已弃用,并已在PHP 7.2中删除。 因为加密对于系统是必不可少的,事后很难更改,所以我花了几个小时阅读有关PHP对称加密的最新最佳实践,最后得到了AES 256 GCM。

AES (AES)

In the old mcrypt based version, I was using Rijndael 128 CBC. AES is a subset of Rijndael and sometimes the names are used interchangeably. AES always has a block size of 128 and only supports 128, 192, and 256-bit keys, while Rijndael is defined for all block sizes and keys from 128 to 256 in 32-bit increments. As the name Advanced Encryption Standard suggests, AES is the standard encryption method for many organizations and companies. AES 192 and 256 are also used for documents with the highest security clearance in the US. There are a few theoretical attacks to AES, but none of them is practical with current hardware. Because of its high security and wide support, AES is the logical choice for an encryption algorithm.

在基于mcrypt的旧版本中,我使用的是Rijndael 128 CBC。 AES是Rijndael的子集,有时名称可以互换使用。 AES的块大小始终为128,并且仅支持128、192和256位密钥,而Rijndael为所有块大小和从128到256的密钥定义了32位增量。 就像高级加密标准的名称所暗示的那样,AES是许多组织和公司的标准加密方法。 AES 192和256也用于美国安全性最高的文档。 对AES进行了一些理论上的攻击,但是对于当前的硬件来说,没有一种是可行的。 由于其高安全性和广泛的支持,AES是加密算法的合理选择。

GCM和CBC (GCM vs CBC)

The biggest change in the new encryption method is going from CBC to GCM. CBC and GCM are different modes in the AES algorithm. CBC has been invented in the 70s and since then a few theoretical attacks on it have been discovered. Depending on the situation, it is still safe enough in most cases, but nowadays GCM is recommended. GCM was published in 2004 and is considered to be a lot safer. It also has a built-in authentication check, which means the integrity of the message can be confirmed.

新加密方法的最大变化是从CBC到GCM。 CBC和GCM是AES算法中的不同模式。 CBC于70年代发明,此后发现了一些理论上的攻击。 根据情况,在大多数情况下它仍然足够安全,但是现在建议使用GCM。 GCM于2004年发布,被认为更加安全。 它还具有内置的身份验证检查,这意味着可以确认消息的完整性。

Another advantage is that in GCM the encryption and decryption can be parallelized, while only the decryption is parallelizable in CBC. This means the encryption of large files can be a lot faster on multicore CPUs, although I doubt the PHP OpenSSL implementation makes use of it, nor do I need it for the small message sizes that I have.

另一个优点是,在GCM中,加密和解密可以并行化,而在CBC中只有解密是可并行化的。 这意味着大文件的加密在多核CPU上可以快得多,尽管我怀疑PHP OpenSSL实现会使用它,对于我拥有的小消息量,我也不需要它。

The biggest difference between the two is the requirements for the initialization vector (IV). CBC requires a strongly randomized IV and gets weaker if a subpar randomization algorithm is used. GCM doesn’t need randomization for the IV but has a major security issue if the same IV is used twice with the same key. In fact, it is possible to use an incremental counter for the IV if you wanted to. Because I plan to use the encryption system for different websites and apps, keeping track of a combined counter for all of them is difficult. However, it is still possible to use a random IV for GCM as long as the same key isn’t used too many times. The IV length for AES 256 GCM is 96 bits, which is on the short side, but there are still 2⁹⁶ possibilities. To be on the safe side the key should only be used about a billion times before switching it. I won’t even get close to that any time soon, so it’s totally fine. Of course, there is a very small chance that the same random IV is picked before that, but at that point, you don’t need to use encryption anyway, because there is also the very low chance that a hacker just guesses the correct key after a few tries.

两者之间最大的不同是初始化向量(IV)的要求。 CBC需要高度随机化的IV,如果使用次优随机化算法,则CBC会变弱。 GCM不需要对IV进行随机化,但是如果将同一IV两次与同一密钥一起使用,则会遇到一个重大的安全问题。 实际上,如果需要,可以为IV使用增量计数器。 由于我计划将加密系统用于不同的网站和应用程序,因此很难跟踪所有这些网站和应用程序的组合计数器。 但是,只要未多次使用同一密钥,仍然可以对GCM使用随机IV。 AES 256 GCM的IV长度为96位,虽然较短,但仍有2/5的可能性。 为了安全起见,在切换密钥之前,只能使用大约十亿次。 我什至不会很快达到这个水平,所以完全可以。 当然,在此之前选择相同的随机IV的可能性很小,但是在那一点上,您无论如何都不需要使用加密,因为黑客猜测正确密钥的可能性也很小。经过几次尝试。

键长 (Key Length)

I also went with a higher key length of 256 bits in the new OpenSSL encryption compared to 128 bits in the mcrypt version. 128-bit keys are still secure enough, especially when used with the added security of GCM. Many companies use AES 128 GCM because of its higher speed compared to AES 256 GCM. However, I don’t want to update the system again and I only have a few users so server performance isn’t a concern. Therefore I might as well use the more secure version.

与mcrypt版本的128位相比,新的OpenSSL加密中的密钥长度也更长,为256位。 128位密钥仍然足够安全,特别是在与GCM的附加安全性一起使用时。 许多公司使用AES 128 GCM,因为它的速度比AES 256 GCM高。 但是,我不想再次更新系统,我只有几个用户,因此服务器性能不是问题。 因此,我不妨使用更安全的版本。

Additionally, only a small subset of my data is encrypted, I don’t store any sensitive information, and I’m not really a target for hackers, so using AES 256 GCM is probably massive overkill, but I cannot hurt either.

此外,我的数据中只有一小部分被加密,我不存储任何敏感信息,而且我并不是真正的黑客目标,因此使用AES 256 GCM可能会造成严重的后果,但是我也不会受到伤害。

实作 (Implementation)

There isn’t anything special about the implementation. Unlike CBC, GCM creates an authorization tag on encryption that needs to be provided to the decryption function, but like the IV it doesn’t need to be secret so it is appended to the result. A change from the mcrypt version is the use of base64 encoding. I didn’t use it before and just stored the binary data in the database, but whenever I had to look at the database the formatting was completely messed up. Base64 encoded text, on the other hand, is human readable and makes the database prettier to look at. It does use a bit more storage space, but I don’t use encryption for a lot of data at the moment, so it’s a minor concern.

关于实现没有什么特别的。 与CBC不同,GCM在加密时会创建一个授权标签,需要将其提供给解密功能,但是像IV一样,它不需要保密,因此可以添加到结果中。 与mcrypt版本不同的是使用了base64编码。 我以前没有使用过它,只是将二进制数据存储在数据库中,但是每当我不得不查看数据库时,格式就完全搞砸了。 另一方面,Base64编码的文本是人类可读的,并使数据库更美观。 它确实使用了更多的存储空间,但是我目前不对大量数据使用加密,因此这是个小问题。

After researching current best practices for encryption in PHP, I went with AES 256 GCM. It is the highest encryption standard and used for top-secret government documents. It is almost certainly complete overkill for my use cases, but what is good enough for the CIA might just be good enough to encrypt how much I spent on groceries each week.

在研究了当前有关PHP加密的最佳实践之后,我选择了AES 256 GCM。 它是最高的加密标准,用于绝密的政府文件。 对于我的用例来说,几乎可以肯定这是完全的矫kill过正,但是对CIA来说足够好的可能只是足以加密我每周在杂货上花费的钱。

翻译自: https://levelup.gitconnected.com/encryption-in-php-cf3ca98f4287

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值