PHP crypt()到Qt

PHP crypt()到Qt,php,qt,cryptography,crypt,Php,Qt,Cryptography,Crypt,我目前正在学习GUI应用程序的Qt5。我的第一个项目是制作一个身份验证脚本并将其连接到我们的数据库 问题是密码列由PHP的crypt()填充,它生成一个以$1$开头的哈希字符串 (例如,echo crypt(“密码”);prints$1$d41.iA3.$XfuFXpCJfxSduzidGnKBR0 如何使用Qt将GUI应用程序中输入的密码与数据库中由crypt()生成的密码列进行比较?TL;DR: 使用密钥派生函数存储密码 PHP的crypt()很难从其他编程语言中使用,因为 它使用一种奇

我目前正在学习GUI应用程序的Qt5。我的第一个项目是制作一个身份验证脚本并将其连接到我们的数据库

问题是密码列由PHP的
crypt()
填充,它生成一个以
$1$
开头的哈希字符串

(例如,
echo crypt(“密码”);
prints
$1$d41.iA3.$XfuFXpCJfxSduzidGnKBR0

如何使用Qt将GUI应用程序中输入的密码与数据库中由
crypt()
生成的密码列进行比较?

TL;DR: 使用密钥派生函数存储密码


PHP的
crypt()
很难从其他编程语言中使用,因为

  • 它使用一种奇怪的方式来混合盐和密码,而不是标准的HMAC
  • 它有自己的base64字母表,需要重新实现
除此之外,您还使用普通md5作为密码哈希算法。 永远不要将md5用于密码哈希


那我们就把手边的衣服弄脏吧

  • crypt()
    s输出的结构如下:其中,没有算法选项的算法
    $1$
    表示MD5
  • 哈希密码为。这可以通过将的输出替换为PHPs字母表来存档
    
    ABCDEFGHIJKLMNOPQRSTUVXYZABCDFGHIJKLMNOPQRSTUVXYZ0123456789+/
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    /0123456789abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz
    
    或者,如果性能重要,则重新实现base64
  • 从实现中可以看出,最多使用8个字符的盐(
    d41.iA3.
    是您的情况)
  • 然后md5的输入被构造为
    foo=password | |$$1$| | salt
    ,其中
    |
    是字符串串联。使用QByteArray作为
    foo
    的类型
  • 计算md5(密码| | |盐| |密码)并将其称为
    bar
  • 设置
    bar='\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
  • 长度(密码)
    字节从
    bar
    (二进制表示)中剪切下来,并将其附加到
    foo
    。如果
    length(密码)>16,则根据需要重复
    bar
  • Uff,让我引用原始来源,然后是一些非常奇怪的东西

    我希望我能从源头上做好准备

  • 运行:
    bar=md5(foo)
  • 那样做

    for (i = 0; i < 1000; i++) {
        moo = ""
        if (i & 1) {
            moo += password
        }
        else {
            moo += bar
        }
        if (i % 3) {
            moo += salt
        }
        if (i % 7) {
            moo += password
        }
        if (i & 1) {
            moo += bar
        }
        else {
            moo += password
        }
        bar = md5(moo)
    }
    
    (i=0;i<1000;i++)的
    {
    moo=“”
    如果(i&1){
    moo+=密码
    }
    否则{
    moo+=巴
    }
    如果(i%3){
    moo+=盐
    }
    如果(i%7){
    moo+=密码
    }
    如果(i&1){
    moo+=巴
    }
    否则{
    moo+=密码
    }
    bar=md5(moo)
    }
    
  • 把所有东西粘在一起:
    $1$| | | |$| | | | base64(bar)

  • TL;DR: 使用密钥派生函数存储密码


    PHP的
    crypt()
    很难从其他编程语言中使用,因为

    • 它使用一种奇怪的方式来混合盐和密码,而不是标准的HMAC
    • 它有自己的base64字母表,需要重新实现
    除此之外,您还使用普通md5作为密码哈希算法。 永远不要将md5用于密码哈希


    那我们就把手边的衣服弄脏吧

  • crypt()
    s输出的结构如下:其中,没有算法选项的算法
    $1$
    表示MD5
  • 哈希密码为。这可以通过将的输出替换为PHPs字母表来存档
    
    ABCDEFGHIJKLMNOPQRSTUVXYZABCDFGHIJKLMNOPQRSTUVXYZ0123456789+/
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    /0123456789abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz
    
    或者,如果性能重要,则重新实现base64
  • 从实现中可以看出,最多使用8个字符的盐(
    d41.iA3.
    是您的情况)
  • 然后md5的输入被构造为
    foo=password | |$$1$| | salt
    ,其中
    |
    是字符串串联。使用QByteArray作为
    foo
    的类型
  • 计算md5(密码| | |盐| |密码)并将其称为
    bar
  • 设置
    bar='\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'
  • 长度(密码)
    字节从
    bar
    (二进制表示)中剪切下来,并将其附加到
    foo
    。如果
    length(密码)>16,则根据需要重复
    bar
  • Uff,让我引用原始来源,然后是一些非常奇怪的东西

    我希望我能从源头上做好准备

  • 运行:
    bar=md5(foo)
  • 那样做

    for (i = 0; i < 1000; i++) {
        moo = ""
        if (i & 1) {
            moo += password
        }
        else {
            moo += bar
        }
        if (i % 3) {
            moo += salt
        }
        if (i % 7) {
            moo += password
        }
        if (i & 1) {
            moo += bar
        }
        else {
            moo += password
        }
        bar = md5(moo)
    }
    
    (i=0;i<1000;i++)的
    {
    moo=“”
    如果(i&1){
    moo+=密码
    }
    否则{
    moo+=巴
    }
    如果(i%3){
    moo+=盐
    }
    如果(i%7){
    moo+=密码
    }
    如果(i&1){
    moo+=巴
    }
    否则{
    moo+=密码
    }
    bar=md5(moo)
    }
    
  • 把所有东西粘在一起:
    $1$| | | |$| | | | base64(bar)


  • 如果MD5在密钥派生函数(例如PBKDF2)中正确应用,则MD5是安全的。当然,最好使用一个已知的好函数,如SHA-2哈希函数之一。对于PBKDF2,可以选择SHA1,因为它具有更广泛的可用性和兼容性。嗯,实际上,当我来到这里时,数据库中已经填充了成千上万的用户,我可以推荐,但是没有办法用QT模仿PHP密码吗?我的意思是,如果使用相同的字符串和salt,则生成相同的哈希字符串?感谢r