关于php:良好的加密哈希函数

Good cryptographic hash functions

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Secure hash and salt for PHP passwords

我正在创建一个网站,我需要一个安全的算法来存储密码。我刚开始考虑BCRYPT,但后来发现我的主机不支持它,我无法更改主机。

我的主机允许此加密:

  • 标准DES

这些散列:

  • MD5
  • MD2、MD4和MD5
  • sha1、sha256、sha384和sha512
  • ripemd128、ripemd160、ripemd256和ripemd360
  • 漩涡
  • Tiger128,3、Tiger160,3、Tiger192,3、Tiger128,4、Tiger160,4和Tiger192,4
  • 斯内弗鲁
  • 高尔斯
  • 阿德勒32
  • CRC32和CRC32B
  • 哈维尔128,3、哈维尔160,3、哈维尔192,3、哈维尔224,3、哈维尔256,3、哈维尔128,4、哈维尔160,4、哈维尔192,4、哈维尔224,3、哈维尔256,4、哈维尔128,5、哈维尔160,5、哈维尔192,5、哈维尔224,5&;哈维尔256,5

所以,你们中有人能用这个和盐来修正一个好的算法吗?


你根本不应该存储加密的(甚至是非加密的)密码。相反,使用盐散列(拉伸,例如使用PBKdf2),最好是sha2-512。

以下是所列哈希的分类(详见维基百科),仅供参考:

加密(不是哈希函数):des
非加密校验和(可笑):adler32,crc32,crc32b
断开:md2,md4,md5,sha1
可能断了:Tiger,Snefru,Gost,Haval*
可能安全:sha2-256/384/512,ripemd-128/256,ripemd-160/320,whirlpool

请注意,强度指的是查找任何与已知哈希匹配的密码的攻击(预映像攻击)。此外,上述排序是偏执的,会立即丢弃任何具有已知漏洞的哈希。


您应该将密码存储为上面提到的散列值,而不是加密的。

哈希函数基本上是一种单向转换,它总是为相同的输入参数生成相同的哈希。不能将哈希转换回其原始形式,否则将认为哈希函数已损坏。

加密是一种双向转换,在这种转换中,如果您有密钥,可以将加密的数据转换回其原始形式。

通过将密码存储为散列,并且由于它们是单向转换的,所以即使有人要获取数据库,也无法提取它们。

当检查密码时,只需使用与存储密码相同的哈希函数对其进行转换,并对照数据库进行检查。


你应该

  • 用盐做土豆泥的一部分。
  • 使用10000+迭代范围内的迭代例程。例如,pbkdf 2。
  • 使用已知的强哈希(sha-256、sha-512)

CRC32、ADLER32等并不是为了加密安全而设计的——它们只是快速校验和算法。我认为Salted SHA-256应该提供安全性和兼容性的良好组合。

有一点不太严重,我记得我曾经在一个缓慢的服务器上使用过salted md5,该服务器预计可以存储中等负载。所以我决定用一个32位的随机盐填充它,并将整个内容存储为十六进制——这给人的印象是整个内容都是未加安全盐的sha-1。我真诚地希望有人浪费宝贵的时间在被偷的垃圾场上经营彩虹桌!

安全性并不完全是关于更昂贵的哈希:)


正如gnur所说,您需要决定是否要散列或加密密码。如果这些是您自己的用户的密码,并且密码只在您的系统上使用,那么可以使用salt和strength来散列它们。在可用的哈希算法中,可以使用sha-256或sha-512。对于salt,使用128个随机位(16字节)。理想情况下使用加密RNG,尽管非加密RNG在紧要关头也能做到。假定袭击者知道盐。扩展到处理单个密码大约需要0.1秒。这将任何攻击者限制为每秒10次尝试破坏密码。

如果要存储登录到外部系统的密码,则需要对密码进行加密,并在需要时对其进行解密。DES是您在这里的唯一真正选择,除非您也有3DES(又名三重DES或DESEDE)可用。我很惊讶AES/Rijndael不可用。如果是的话,我们会优先选择DES。