使用 PHP 最简单的双向加密
在常见 PHP 安装中进行双向加密的最简单方法是什么?
我需要能够使用字符串密钥加密数据,并使用相同的密钥在另一端解密。
安全性并不像代码的可移植性那么重要,因此我希望能够使事情尽可能简单。目前,我正在使用 RC4 实现,但如果我能找到本机支持的东西,我想我可以节省很多不必要的代码。
What is the simplest way of doing two way encryption in common PHP installs?
I need to be able to encrypt data with a string key, and use the same key to decrypt on the other end.
The security isn't as big of a concern as the portability of the code, so I'd like to be able to keep things as simple as possible. Currently, I am using an RC4 implementation, but if I can find something natively supported I figure I can save a lot of unnecessary code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
重要:除非您有非常特定的用例,不加密密码,而是使用密码哈希算法。当有人说他们在服务器端应用程序中加密他们的密码时,他们要么不知情,要么正在描述危险的系统设计。 安全存储密码是一个完全独立的问题加密。
获悉情况。设计安全系统。
PHP 中的便携式数据加密
如果您使用 PHP 5.4 或更高版本 并且不想编写加密技术如果您自己模块,我建议使用提供经过身份验证的加密的现有库。我链接的库仅依赖于 PHP 提供的内容,并且由少数安全研究人员定期审查。 (包括我自己。)
如果您的可移植性目标不妨碍需要 PECL 扩展,libsodium< /strong> 比您或我可以用 PHP 编写的任何内容都强烈推荐。
更新 (2016-06-12): 您现在可以使用 sodium_compat 并使用无需安装 PECL 扩展即可提供相同的 crypto libsodium。
如果您想尝试密码学工程,请继续阅读。
首先,您应该花时间了解危险未经身份验证的加密和密码毁灭原理。
加密和解密
PHP 中的加密实际上很简单(我们将使用
openssl_encrypt()
和openssl_decrypt()
一旦你做出了一些决定要加密您的信息,请参阅openssl_get_cipher_methods()
以获取您的系统支持的方法列表。最好的选择是 CTR 模式下的 AES:aes-128-ctr
aes-192-ctr
aes-256-ctr
目前没有理由相信AES 密钥大小是一个需要担心的重要问题(由于 256- 中的密钥调度不良,可能并不是越大越好)位模式)。
注意:我们没有使用
mcrypt
,因为它是废弃软件 并且存在可能影响安全的未修补的错误。由于这些原因,我鼓励其他 PHP 开发人员也避免使用它。使用 OpenSSL 的简单加密/解密包装器使用
示例
演示:https://3v4l.org/jl7qR
上面的简单加密库使用起来仍然不安全。我们需要在解密之前验证密文并验证它们。
注意:默认情况下,
UnsafeCrypto::encrypt()
将返回原始二进制字符串。如果您需要以二进制安全格式(base64 编码)存储它,请这样调用:演示:http://3v4l.org/f5K93
简单身份验证包装器
使用示例
演示:原始二进制文件,base64 编码
如果有人希望使用此
生产环境中的 SaferCrypto
库,或者您自己实现相同概念,我强烈建议您联系您的常驻密码学家以获取更多信息之前的第二意见 你做。他们会告诉你我可能没有意识到的错误。使用 会更好一个有信誉的密码学库。
Important: Unless you have a very particular use-case, do not encrypt passwords, use a password hashing algorithm instead. When someone says they encrypt their passwords in a server-side application, they're either uninformed or they're describing a dangerous system design. Safely storing passwords is a totally separate problem from encryption.
Be informed. Design safe systems.
Portable Data Encryption in PHP
If you're using PHP 5.4 or newer and don't want to write a cryptography module yourself, I recommend using an existing library that provides authenticated encryption. The library I linked relies only on what PHP provides and is under periodic review by a handful of security researchers. (Myself included.)
If your portability goals do not prevent requiring PECL extensions, libsodium is highly recommended over anything you or I can write in PHP.
Update (2016-06-12): You can now use sodium_compat and use the same crypto libsodium offers without installing PECL extensions.
If you want to try your hand at cryptography engineering, read on.
First, you should take the time to learn the dangers of unauthenticated encryption and the Cryptographic Doom Principle.
Encryption and Decryption
Encryption in PHP is actually simple (we're going to use
openssl_encrypt()
andopenssl_decrypt()
once you have made some decisions about how to encrypt your information. Consultopenssl_get_cipher_methods()
for a list of the methods supported on your system. The best choice is AES in CTR mode:aes-128-ctr
aes-192-ctr
aes-256-ctr
There is currently no reason to believe that the AES key size is a significant issue to worry about (bigger is probably not better, due to bad key-scheduling in the 256-bit mode).
Note: We are not using
mcrypt
because it is abandonware and has unpatched bugs that might be security-affecting. Because of these reasons, I encourage other PHP developers to avoid it as well.Simple Encryption/Decryption Wrapper using OpenSSL
Usage Example
Demo: https://3v4l.org/jl7qR
The above simple crypto library still is not safe to use. We need to authenticate ciphertexts and verify them before we decrypt.
Note: By default,
UnsafeCrypto::encrypt()
will return a raw binary string. Call it like this if you need to store it in a binary-safe format (base64-encoded):Demo: http://3v4l.org/f5K93
Simple Authentication Wrapper
Usage Example
Demos: raw binary, base64-encoded
If anyone wishes to use this
SaferCrypto
library in a production environment, or your own implementation of the same concepts, I strongly recommend reaching out to your resident cryptographers for a second opinion before you do. They'll be able tell you about mistakes that I might not even be aware of.You will be much better off using a reputable cryptography library.
已编辑:
您确实应该使用 openssl_encrypt() & openssl_decrypt()
作为斯科特 说,Mcrypt 不是一个好主意,因为它自 2007 年以来就没有更新过。
甚至有一个 RFC 从 PHP 中删除 Mcrypt - https://wiki.php.net/rfc/mcrypt-viking-funeral
Edited:
You should really be using openssl_encrypt() & openssl_decrypt()
As Scott says, Mcrypt is not a good idea as it has not been updated since 2007.
There is even an RFC to remove Mcrypt from PHP - https://wiki.php.net/rfc/mcrypt-viking-funeral
使用
mcrypt_encrypt()
和mcrypt_decrypt()
以及相应的参数。非常简单直接,而且您使用经过实战检验的加密包。编辑
在此回答后 5 年零 4 个月,
mcrypt
扩展现在正在弃用并最终从 PHP 中删除。Use
mcrypt_encrypt()
andmcrypt_decrypt()
with corresponding parameters. Really easy and straight forward, and you use a battle-tested encryption package.EDIT
5 years and 4 months after this answer, the
mcrypt
extension is now in the process of deprecation and eventual removal from PHP.使用 openssl_encrypt() 进行加密
openssl_encrypt 函数提供了一种安全且简单的方法来加密数据。
在下面的脚本中,我们使用 AES128 加密方法,但您可以根据您要加密的内容考虑其他类型的加密方法。
以下是所使用变量的解释:
message_to_encrypt :要加密的数据
Secret_key :这是您的加密“密码”。一定不要选择太简单的东西,并小心不要与其他人分享你的密钥
method :加密方法。这里我们选择AES128。
iv_length 和 iv :使用字节准备加密
crypto_message :包含加密消息的变量
使用 openssl_decrypt() 解密
现在您已加密数据,您可能需要解密它才能重新使用您首先包含在变量中的消息。为此,我们将使用函数 openssl_decrypt()。
openssl_decrypt() 提出的解密方法与 openssl_encrypt() 接近。
唯一的区别是,您需要添加已加密的消息作为 openssl_decrypt() 的第一个参数,而不是添加 $message_to_encrypt。
注意:需要保存密钥和 iv 才能解密。
Encrypting using openssl_encrypt()
The openssl_encrypt function provides a secured and easy way to encrypt your data.
In the script below, we use the AES128 encryption method, but you may consider other kind of encryption method depending on what you want to encrypt.
Here is an explanation of the variables used :
message_to_encrypt : the data you want to encrypt
secret_key : it is your ‘password’ for encryption. Be sure not to choose something too easy and be careful not to share your secret key with other people
method : the method of encryption. Here we chose AES128.
iv_length and iv : prepare the encryption using bytes
encrypted_message : the variable including your encrypted message
Decrypting using openssl_decrypt()
Now you encrypted your data, you may need to decrypt it in order to re-use the message you first included into a variable. In order to do so, we will use the function openssl_decrypt().
The decrypt method proposed by openssl_decrypt() is close to openssl_encrypt().
The only difference is that instead of adding $message_to_encrypt, you will need to add your already encrypted message as the first argument of openssl_decrypt().
Note: The secret key and iv needs to be saved in order to decrypt.
PHP 7.2 完全脱离了
Mcrypt
,现在的加密基于可维护的Libsodium
库。您所有的加密需求都可以通过
Libsodium
库基本解决。Libsodium 文档:https://github.com/paragonie/pecl-libsodium-doc
PHP 7.2 moved completely away from
Mcrypt
and the encryption now is based on the maintainableLibsodium
library.All your encryption needs can be basically resolved through
Libsodium
library.Libsodium documentation: https://github.com/paragonie/pecl-libsodium-doc
重要这个答案仅对 PHP 5 有效,在 PHP 7 中使用内置加密函数。
这是简单但足够安全的实现:
代码和示例位于:https://stackoverflow.com/a/19445173/1387163
IMPORTANT this answer is valid only for PHP 5, in PHP 7 use built-in cryptographic functions.
Here is simple but secure enough implementation:
Code and examples are here: https://stackoverflow.com/a/19445173/1387163