如何使用Node.js的crypto库生成一个scrypt哈希?

4
function sha512(s){
    var sha = crypto.createHash('sha512');
    sha.update(s);
    return sha.digest('hex');
};
exports.sha512 = sha512;

我现在正在使用这个,但我想切换到 scrypt。 我该怎么做?


Node的加密库不支持scrypt。由于scrypt尚未标准化,因此在加密中实现scrypt似乎也不会成为未来的趋势。您应该使用node-scrypt,它包装了本地C ++ scrypt实用程序。 - tsturzl
同时,Node的Crypto支持scrypt。Node 10.5+。 - smonkey
scrypt-kdf 是一个封装了核心 Node.js 加密实现的包,提供了 kdf()verify() 函数。 - ChrisV
3个回答

8

您应该使用node-scrypt

它有清晰的 API 和良好的文档。

var scrypt = require("scrypt");
var scryptParameters = scrypt.params(0.1);

var key = new Buffer("this is a key"); //key defaults to buffer in config, so input must be a buffer

//Synchronous example that will output in hexidecimal encoding
scrypt.hash.config.outputEncoding = "hex";
var hash = scrypt.hash(key, scryptParameters); //should be wrapped in try catch, but leaving it out for brevity
console.log("Synchronous result: "+hash);

//Asynchronous example that expects key to be ascii encoded
scrypt.hash.config.keyEncoding = "ascii";
scrypt.hash("ascii encoded key", {N: 1, r:1, p:1}, function(err, result){
    //result will be hex encoded
    //Note how scrypt parameters was passed as a JSON object
    console.log("Asynchronous result: "+result);
});

2
请注意:截至目前,scrypt不支持node版本0.11或新发布的版本0.12。 - trysis
3
警告!!!这个模块已不再使用。请使用https://nodejs.org/api/crypto.html#crypto_crypto_scrypt_password_salt_keylen_options_callback代替。 - Damien

1
我会提供我的实现方式:https://www.npmjs.org/package/scryptsy
以下是示例:
var scrypt = require('scryptsy') //npm install --save scryptsy

var key = "pleaseletmein" //can be of type 'Buffer'
var salt = "SodiumChloride" //can be of type 'Buffer'
var data = scrypt(key, salt, 16384, 8, 1, 64)
console.log(data.toString('hex')) 
// => 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887

这里有文档:http://cryptocoinjs.com/modules/crypto/scryptsy/


你会如何建议在“检查用户登录凭据”场景中使用它?我假设仅让Web应用程序运行哈希本身会导致主要减速(因为Node.js是单线程的),所以您是否建议将该工作卸载到第二个仅哈希的应用程序中,主应用程序向其发出异步HTTP请求? - Josh1billion
是的,你说得对,否则会影响你的Web应用程序性能。我会使用集群或child_process.fork。 - JP Richardson
好的,我会研究一下这些选项。谢谢您的见解。 - Josh1billion

1

这是一个简化的barrysteyn/node-scrypt同步示例,包含(反)序列化:

    let scrypt = require('scrypt')
    let scryptParameters = scrypt.paramsSync(0.1)

    function encode(s) {
      return scrypt.kdfSync(s, scryptParameters).toString('Base64')
    }

    function verify(encoded, s) {
      return scrypt.verifyKdfSync(new Buffer(encoded, 'Base64'), s)
    }

    // Example:
    let s = encode('my password')  // c2NyeXB0AAwAAAAI....
    verify(s, 'my password')   //true
    verify(s, 'my pa$$word')   //false

在Node 7.0.0和scrypt 6.0.3上进行测试。


自 node v6.0.0 起,使用 new Buffer(string[, encoding]) 已被弃用,应改用 Buffer.from(string[, encoding])来源 无论如何都很有帮助;文档对于应该放入 verifykdf 函数的类型非常不清楚。 - MagicLegend

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接