在密码哈希中合并密码到期日期的最佳方法



我写了一些基于 PHP5s password_hash和password_verify函数的 JS 函数。这基本上只是一种更简单的方法,可以生成一个用随机盐散列的密码,并验证所述密码,而无需单独存储盐。

    function passwordHash ( password ) {
        if( ! password )
            throw new Error('No password was given to hash')
        if( ! _.isString( password ) )
            throw new Error('Must provide a STRING as a password')
        // Generate the salt
        // THIS MUST NOT CHANGE! If this value is not the same as what
        // passwordVerify expects, no hash will be validated
        const salt = randStr( 20 )
        // Return the salted hash with the salt prepended to it
        return salt + makeHash( password, salt )
    }
    function passwordVerify ( password, passwdHash ) {
        if( ! password || ! passwdHash )
            throw new Error('Need to provide both a password and a hash to verify')
        if( ! _.isString( password ) || ! _.isString( passwdHash ) )
            throw new Error('Password and hash both need to be strings')
        // If the hash isn't even the proper length, don't bother checking
        if( passwdHash.length !== 108 )
            return false
        // Get the salt from the password hash - first 20 chars
        const salt = passwdHash.substr( 0, 20 )
        // Get the password hash, everything after the first 20 chars
        const hash = passwdHash.substr( 20 )
        // Check the hash against a hash generated with the same data
        return makeHash( password, salt ) === hash
    }
    function makeHash ( str, salt ) {
        if( ! _.isString( str ) || ! _.isString( salt ))
            throw new Error('_.hash() requires two string parameters, a string to hash and a salt')
        const h = crypto.createHash('sha512')
        h.update(str)
        h.update(salt)
        return h.digest('base64')
    }

下面是一个正在使用的示例:

    <!-- language: lang-js -->
    const hash = _.passwordHash( 'secret' )
    _.passwordVerify( 'secret', hash ) === true
    _.passwordVerify( 'terces', hash ) === false
我一直在寻找一种在哈希中合并到期日期

的方法,这意味着如果在生成哈希时提供了日期,那么截止日期将合并到哈希中(因此不是纯文本(。例:

    <!-- language: lang-js -->
    const hash = _.passwordHash({
        'password'   : 'secret',
        'expiration' : new Date(new Date().getTime() + (24 * 60 * 60 * 1000))
    })
    // If ran within 24 hours of when it was generated
    _.passwordVerify( 'secret', hash ) === true
    // If ran later than 24 hours after it was generated
    _.passwordVerify( 'secret', hash ) === false

但是我找不到一种一致的方法来在哈希中包含日期,该日期将在所述日期之后拒绝正确的密码。我想我可以在密码本身旁边存储截止日期的哈希版本,但这并不难利用。

任何意见将不胜感激。

谢谢!

只需使用当前时间散列您的密码,例如:

function passwordHash ( password ) {
    const salt = (+new Date()+"T"+randStr(20)).slice(20);//make shure salt has const length (may increase length due to lowered entropy)
    // Return the salted hash with the salt prepended to it
    return salt + makeHash( password, salt )
}
因此

,现在密码使用当前时间进行哈希处理,因此您可以正常验证哈希。要检查时间,您可以:

 const salt = passwdHash.substr( 0, 20 );
 const time=+salt.split("T")[0];
 //range check
 if(time<+new Date()) throw new Error("Token expired!");

您可以考虑额外存储时间,或者如果需要第三方身份验证,可以创建令牌。

最新更新