草庐IT

php - openssl_digest vs hash vs hash_hmac? SALT 和 HMAC 的区别?

coder 2023-06-15 原文

我想使用 SHA512 来存储密码。要做到这一点,哪一个 openssl_digest , hashhash_hmac我应该使用,为什么?
SALT有什么区别& HMAC ?

我刚刚读到 HMAC 是建立在哈希函数之上的。
SHA512+SALT+HMAC也是如此真的有必要或SHA512+SALTSHA512+HMAC ?

最佳答案

所以,首先,让我们弄清楚一件事。 openssl_digest() === hash() .它只是另一个名称不同的函数,它执行完全相同的操作。它计算输入的加密哈希。

所以,现在我们有一个问题:存储密码时,哪个更好:hashhash_hmac ?

简答:

两者都不

长答案:

事实证明,The Rainbow Table Is Dead .只是使用 hash($password . $salt)甚至 hash_hmac($password, $salt)不足以存储密码。时期。如果您正在这样做,请立即停止。

原因很简单:计算机(或 GPU)上的计算时间非常便宜。它太便宜了,以至暴力破解密码列表足够便宜,您需要担心它。请记住,哈希函数被设计得很快。不贵啊...

但是,事实证明,有一种方法可以使这些快速散列函数更加昂贵。事实上,它非常简单:迭代。

现在,我知道你在想什么。你只需要遍历哈希:

function hash_password($password, $salt) {
    $hash = hash("sha512", $password . $salt);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash("sha512", $hash);
    }
}

这当然够好了,对吧?不。如 Fundamental Difference Between Hashing and Encryption 中所述,这不是一个好主意。那么为什么不直接反馈密码并再次加盐呢?
function hash_password($password, $salt) {
    $hash = hash("md5", $salt . $password);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash("md5", $hash . $password);
    }
}

其实这正是PHPASS使用(略有调整,但这是基本算法)...

所以现在 1 次调用 hash_password执行 1000 个哈希周期。

但是我们可以改进吗?

好吧,事实证明,我们可以。下一个合乎逻辑的事情是看看我们是否可以在相同的时间内获得更多的哈希周期。这就是hash_hmac()进来了。事实证明,HMAC每次调用时使用 2 个哈希周期。而且因为都是C,所以只需要hash()的1.5倍左右的时间。需要做一个回合。

所以这意味着如果我们替换 hashhash_hmac ,我们可以立即看到在指定时间内完成的工作量增加了 33%。所以现在我们在这里:
function hash_password($password, $salt) {
    $hash = hash_hmac("md5", $salt, $password);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash_hmac("md5", $hash, $password);
    }
}

这实际上是 PBKDF2 的基本内循环.

但我们能变得更好吗?

是的,再一次,我们可以变得更好。如果我们仔细观察,我们会发现——除了密码和盐之外——上述所有算法都使用了非常少的内存。在 sha512 的情况下,他们将使用大约 128 到 256 个字节(缓冲区和状态)来散列密码。由于内存使用量非常小,因此在 GPU 中同时并排运行很多内存是微不足道的。如果我们只能增加内存使用...

好吧,事实证明,我们可以简单地使用 bcrypt ,这是一种自适应哈希算法。它的优点是它比上述算法使用更多的内存(大约 4 到 5kb)。所以它更难并行化。由于计算成本高昂,因此它对暴力破解具有抵抗力。

幸运的是,它可用于 PHP:
crypt($password, '$2y$07$usesomesillystringforsalt$')

请注意 crypt()使用许多算法,但 $2y$$2a$算法是 bcrypt .

但是我们可以改进吗?

的种类。有一个相对较新的算法叫做scrypt .它比 bcrypt 更好,因为它在计算上同样昂贵,但使用了更多的内存(大约 20mb 到 40mb 来散列单个密码)。因此,它更难以并行化......

不幸的是,scrypt在 PHP 中尚不可用(我正在努力改变它)。在此之前,请使用 bcrypt ...

边注

经过最近的教训LinkedIn , LastFM , Hotmail , Gawker等,证据很明显很多的人做错了。不要做错,使用带有经过审查的算法的库。使用 CRYPT_BLOWFISH (bcrypt),使用 PHPASS,使用 PasswordLib .但是不要仅仅因为你不想拉依赖关系就发明你自己的......那只是疏忽。

更多阅读:
  • Properly Salting Passwords - The Case Against Pepper
  • GPU Accelerated PBKDF2
  • Many Hash Iterations, Append Salt Every Time?
  • MD5 Decoding, How Do They Do It
  • 关于php - openssl_digest vs hash vs hash_hmac? SALT 和 HMAC 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8952807/

    有关php - openssl_digest vs hash vs hash_hmac? SALT 和 HMAC 的区别?的更多相关文章

    1. 神州数码无线产品(AC+AP)配置 - 2

      注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配

    2. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

      按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

    3. c# - 在 C# 中重现 Ruby OpenSSL private_encrypt 输出 - 2

      我有一个简单的Ruby脚本,我用它在某些HTTPheader上执行private_encrypt以签署要发送到ruby​​RESTAPI的Web请求,该API会根据Base64编码字符串测试Base64编码字符串生成而不是解码Base64和解密数据然后测试原始字符串。我使用的脚本是require"openssl"require"base64"path_to_cert=ARGV[0].dupplain_text=Base64.decode64(ARGV[1].dup)private_key=OpenSSL::PKey::RSA.new(File.read(path_to_cert))pu

    4. ruby - 使用 OpenSSL ruby​​ 从一个 .p12 文件中提取多个 key - 2

      我想知道如何从Apple.p12文件中提取key。根据我有限的理解,.p12文件是X504证书和私钥的组合。我看到我遇到的每个.p12文件都有一个X504证书和至少一个key,在某些情况下有两个key。这是因为每个.p12都有一个Apple开发人员key,有些还有一个额外的key(可能是Appleroot授权key)。我只考虑那些具有两个key的.p12文件是有效的。我的目标是区分具有一个key的.p12文件和具有两个key的.p12文件。到目前为止,我已经使用OpenSSL来检查X504文件和任何.p12的key。例如,我有这段代码可以检查目录中的所有.p12文件:Dir.glob(

    5. 更新证书后,Ruby Net::HTTP 响应 OpenSSL::SSL::SSLError "certificate verify failed" - 2

      我们最近更新了我们网站的SSL证书,在MacOSElCapitan10.11.3上出现以下情况:require'net/http'Net::HTTP.getURI('https://www.google.com')#=>"..."#ThesitewhosecertificategotrenewedNet::HTTP.getURI('https://www.example.com')#=>OpenSSL::SSL::SSLError:SSL_connectreturned=1errno=0state=error:certificateverifyfailed我在Google和StackO

    6. ruby - 为什么 openssl 在 windows 上产生错误但在 centos 上不产生错误:PKCS12_parse: mac verify failure (OpenSSL::PKCS12::PKCS12Error) - 2

      require'openssl'ifARGV.length==2pkcs12=OpenSSL::PKCS12.new(File.read(ARGV[0]),ARGV[1])ppkcs12.certificateelseputs"Usage:load_cert.rb"end运行它会在Windows上产生错误,但在Linux上不会。错误:OpenSSL::PKCS12::PKCS12Error:PKCS12_parse:macverifyfailurefrom(irb):21:ininitializefrom(irb):21:innewfrom(irb):21fromC:/Ruby192/

    7. Ruby OpenSSL 非对称加密——使用两个 key 对 - 2

      我想使用两个key对在两个通信系统之间实现具有不可否认性的安全消息传递。我使用以下方法生成并存储了两组key对:sys1_key=OpenSSL::PKey::RSA.generate(2048)sys2_key=OpenSSL::PKey::RSA.generate(2048)这两个key对都将其单独的公钥和私钥保存到文件中:sys1.pub.pemsys1.priv.pemsys2.pub.pemsys2.priv.pem系统1有自己的公钥和私钥以及系统2的公钥。系统2有自己的公钥和私钥以及系统1的公钥。在系统1上,我想获取消息“Helloworld”并使用系统1的私钥和系统2的公

    8. ruby - OpenSSL 验证来自自己 CA 的证书 - 2

      大家好,感谢您花时间阅读本文。我需要验证由我自己的CA颁发的证书,我有一个证书。我怎样才能做相当于openssl的openssl验证-CAfile在Ruby代码中?OpenSSL的RDoc在这方面不是很有帮助。我试过:require'openssl'ca=OpenSSL::X509::Certificate.new(File.read('ca-cert.pem'))lic=OpenSSL::X509::Certificate.new(File.read('cert.pem'))putslic.verify(ca)但我得到:test.rb:7:in`verify':wrongargume

    9. ruby-on-rails - 使用 OpenSSL 读取证书文件时出现 Ruby 错误 - 2

      我想做一个简单的OpenSSL::X509::Certificate.new(File.read("testuser.p12"))来自带有ruby1.8.7(或1.9.2)的irb,两者的结果相同。我得到的错误是OpenSSL::X509::CertificateError:nestedasn1error这是ruby问题,还是表明证书本身格式不正确?我发现一些类似的报告围绕着证明此类错误的亚马逊证书展开,结果证明是证书本身。它虽然在浏览器中工作。有关如何解决此问题的建议? 最佳答案 根据后缀,“testuser.p12”似乎是一个P

    10. ruby-on-rails - Rails 还是 Sinatra? PHP程序员入门学习哪个好? - 2

      按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?

    随机推荐