使用 PHP 加密和解密密码的最佳方法?
可能的重复:
PHP 2 路加密:我需要存储可以检索的密码
我计划在我的网站上存储用户的外国帐户信息,又名 Rapidshare 用户名和密码等...我想保证信息安全,但我知道如果我散列他们的信息,我无法检索它以供以后使用。
Base64 是可解密的,因此直接使用它是没有意义的。 我的想法是对用户进行扰乱,并在其经过 Base64 处理之前和之后通过,即使在解密之后,如果您尝试解密,也会得到一些看起来很有趣的文本。是否有一个 php 函数接受的值会对字符串进行唯一的加扰,并在稍后重新输入该值时对其进行解扰?
有什么建议吗?
Possible Duplicate:
PHP 2-way encryption: I need to store passwords that can be retrieved
I plan to store foreign account information for my users on my website, aka rapidshare username and passwords, etc... I want to keep information secure, but I know that if I hash their information, I can't retrieve it for later use.
Base64 is decrypt-able so there's no point using that just plain off.
My idea is to scramble the user and pass before and after it gets base64ed that way even after you decrypt it, you get some funny looking text if you try to decrypt. Is there a php function that accepts values that will make an unique scramble of a string and de-scramble it later when the value is reinputed?
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您不应该加密密码,而应该使用 bcrypt 等算法对它们进行哈希处理。 这个答案解释了如何在 PHP 中正确实现密码哈希。不过,这里是您如何加密/解密的方法:
加密:
解密:
警告:上面的示例对信息进行了加密,但没有对密文进行身份验证以防止篡改。 您不应依赖未经身份验证的加密来进行加密安全性,特别是因为所提供的代码容易受到 padding oracle 攻击。
另请参阅:
另外,不要只使用“密码”作为加密密钥。 加密密钥是随机字符串。
3v4l.org 上的演示:
You should not encrypt passwords, instead you should hash them using an algorithm like bcrypt. This answer explains how to properly implement password hashing in PHP. Still, here is how you would encrypt/decrypt:
To Encrypt:
To Decrypt:
Warning: The above example encrypts information, but it does not authenticate the ciphertext to prevent tampering. You should not rely on unauthenticated encryption for security, especially since the code as provided is vulnerable to padding oracle attacks.
See also:
Also, don't just use a "password" for an encryption key. Encryption keys are random strings.
Demo at 3v4l.org:
最近发现了这个课程,它就像梦想一样!
并称其为:
Found this class recently, it works like a dream!
And to call it:
工作示例
working example
在处理加密时,您应该非常注意一件事:
试图变得聪明并发明自己的东西通常会让您感到不安全。
您可能最好使用其中一个加密扩展使用 PHP。
One thing you should be very aware of when dealing with encryption:
Trying to be clever and inventing your own thing usually will leave you with something insecure.
You'd probably be best off using one of the cryptography extensions that come with PHP.
为了处理字符串/数组,我使用这两个函数:
它很灵活,因为您可以通过 URL 存储/发送字符串或数组,因为字符串/数组在加密之前已序列化。
To handle a string / array I use these two functions:
It's flexible as in you can store/send via URL a string or array because the string/array is serialzed before encryption.
这只能为您提供边际保护。如果攻击者可以在您的应用程序中运行任意代码,他们就可以以与您的应用程序完全相同的方式获取密码。如果您将密钥存储在文件中,并使用它在进入数据库的过程中进行加密并在导出时进行解密,那么您仍然可以获得一些针对某些 SQL 注入攻击和错误的数据库备份的保护。但是你应该使用bindparams来完全避免SQL注入的问题。
如果决定加密,您应该为此使用一些高级加密库,否则您将会出错。您必须正确设置密钥、消息填充和完整性检查,否则您所有的加密工作都没有什么用处。 GPGME 是一个不错的选择。 Mcrypt 级别太低,您可能会出错。
This will only give you marginal protection. If the attacker can run arbitrary code in your application they can get at the passwords in exactly the same way your application can. You could still get some protection from some SQL injection attacks and misplaced db backups if you store a secret key in a file and use that to encrypt on the way to the db and decrypt on the way out. But you should use bindparams to completely avoid the issue of SQL injection.
If decide to encrypt, you should use some high level crypto library for this, or you will get it wrong. You'll have to get the key-setup, message padding and integrity checks correct, or all your encryption effort is of little use. GPGME is a good choice for one example. Mcrypt is too low level and you will probably get it wrong.
查看 mycrypt(): http://us.php.net/manual/ en/book.mcrypt.php
如果您使用 postgres,则可以使用 pgcrypto 进行数据库级加密。 (使搜索和排序更容易)
Check out mycrypt(): http://us.php.net/manual/en/book.mcrypt.php
And if you're using postgres there's pgcrypto for database level encryption. (makes it easier to search and sort)
即使您有权访问代码,加密/解密数据库中的数据的最佳想法是使用 2 个不同的密码,每个用户使用私有密码 (
user-pass
),并为所有用户使用私有代码用户(系统通行证
)。场景
用户密码
与md5一起存储在数据库中,用于验证每个用户登录系统。每个用户的用户通行证不同。The best idea to encrypt/decrypt your data in the database even if you have access to the code is to use 2 different passes a private password (
user-pass
) for each user and a private code for all users (system-pass
).Scenario
user-pass
is stored with md5 in the database and is being used to validate each user to login to the system. This user-pass is different for each user.system-pass
for the encryption/decryption of the data. This system-pass is the same for each user.