node.js 哈希字符串?
Posted
技术标签:
【中文标题】node.js 哈希字符串?【英文标题】:node.js hash string? 【发布时间】:2011-08-18 05:34:46 【问题描述】:我有一个要散列的字符串。在 node.js 中生成哈希的最简单方法是什么?
哈希用于版本控制,而不是安全性。
【问题讨论】:
nodejs.org/api/crypto.html 【参考方案1】:如果您只想对一个简单的字符串进行 md5 哈希处理,我发现这对我有用。
var crypto = require('crypto');
var name = 'braitsch';
var hash = crypto.createHash('md5').update(name).digest('hex');
console.log(hash); // 9b74c9897bac770ffc029102a200c5de
【讨论】:
呜呜呜,如果你这样做require('crypto').createHash('md5').update(STRING_TO_BE_HASHED).digest("hex")
,你会得到一个单行。干杯伙伴!
在尝试使用timbooo
的解决方案时多次使用.update
(github.com/joyent/node/issues/749) 遇到一些问题,使用单行修复它(因为每次都重新创建哈希对象)。
如果我有很多字符串要散列,那么继续调用 crypto.createHash 而不是以某种方式重新使用结果会降低效率吗?
md5 是否已被弃用且不安全?
@RedGuy11 它根本没有被弃用。散列密码非常不安全,但是除了密码之外还有许多其他的散列用例。例如,为文件创建 MD5 校验和。【参考方案2】:
看看crypto.createHash(algorithm)
var filename = process.argv[2];
var crypto = require('crypto');
var fs = require('fs');
var md5sum = crypto.createHash('md5');
var s = fs.ReadStream(filename);
s.on('data', function(d)
md5sum.update(d);
);
s.on('end', function()
var d = md5sum.digest('hex');
console.log(d + ' ' + filename);
);
【讨论】:
s.on() 函数在做什么?是否注册了 md5sum.update(d) 函数以在每次从 ReadStream 读取数据时执行? @YoniDor 你试过fs.readsync吗? — 在经典的 while 循环中进行消化,然后确保它已经完成......➝ ***.com/a/21219407/444255 OP 想要散列一个字符串,而不是一个文件。【参考方案3】:Node 的加密模块 API 仍然不稳定。
从 4.0.0 版开始,原生 Crypto 模块不再不稳定。来自official documentation:
加密
稳定性:2 - 稳定
API 已被证明是令人满意的。与 npm 生态系统的兼容性 是一个高优先级,除非绝对必要,否则不会被破坏。
因此,应该认为使用本机实现是安全的,没有外部依赖。
作为参考,当 Crypto 模块仍不稳定时,建议将下面提到的模块作为替代解决方案。
您也可以使用两个模块之一 sha1 或 md5 来完成这项工作。
$ npm install sha1
然后
var sha1 = require('sha1');
var hash = sha1("my message");
console.log(hash); // 104ab42f1193c336aa2cf08a2c946d5c6fd0fcdb
或
$ npm install md5
然后
var md5 = require('md5');
var hash = md5("my message");
console.log(hash); // 8ba6c19dc1def5702ff5acbf2aeea5aa
(MD5 不安全,但经常被 Gravatar 等服务使用。)
这些模块的 API 不会改变!
【讨论】:
我认为使用 Crypto 比引入一个全新的模块更容易和有效。 来自当前的 Node.js 文档:“稳定性:2 - 不稳定;正在讨论未来版本的 API 更改。重大更改将被最小化。” 我的 API模块不会改变。当我最初编写模块时,平台中内置了 nocrypto
模块。另一个优点是您可以在服务器端和客户端使用我的模块。但这完全取决于您,您使用什么库。
加密哈希的构建不断给我“哈希更新失败”BS。最后我搬到了 MD5 模块,它工作得很好。也更容易打电话(稍微)。谢谢。
+1 表示远离 (2) - Crypto API 的不稳定性质的选项!
我通过交换此模块的标准加密使用,在我的 Windows 机器上的节点 0.11.x 上修复了一个奇怪的 sha1 问题。【参考方案4】:
sha256("string or binary");
我遇到了其他答案的问题。我建议您将编码参数设置为 binary
以使用字节字符串并防止 javascript (NodeJS) 和其他语言/服务(如 Python、php、Github...
如果你不使用这段代码,你可以在 NodeJS 和 Python 之间得到不同的哈希值...
如何获得与 Python、PHP、Perl、Github 相同的哈希(并防止出现问题):
NodeJS 正在对字符串的 UTF-8 表示进行哈希处理。其他语言(如 Python、PHP 或 PERL...)正在对字节字符串进行哈希处理。
我们可以添加 binary 参数来使用字节串。
代码:
const crypto = require("crypto");
function sha256(data)
return crypto.createHash("sha256").update(data, "binary").digest("base64");
// ------ binary: hash the byte string
sha256("string or binary");
文档:
crypto.createHash(algorithm[, options]):算法取决于平台上OpenSSL版本支持的可用算法。 hash.digest([encoding]):编码可以是'hex'、'latin1'或'base64'。 (base 64 更长)。您可以通过以下方式解决问题:sha256("\xac")、"\xd1"、"\xb9"、"\xe2"、"\xbb"、"\x93" 等...
其他语言(如 PHP、Python、Perl...)和我使用 .update(data, "binary")
的解决方案:
sha1("\xac") //39527c59247a39d18ad48b9947ea738396a3bc47
Nodejs 默认(无二进制):
sha1("\xac") //f50eb35d94f1d75480496e54f4b4a472a9148752
【讨论】:
【参考方案5】:crypto
模块使这变得非常简单。
设置:
// import crypto from 'crypto';
const crypto = require('crypto');
const sha256 = x => crypto.createHash('sha256').update(x, 'utf8').digest('hex');
用法:
sha256('Hello, world. ');
【讨论】:
【参考方案6】:Simple One Liners:
如果你想要 UTF8 文本哈希:
const hash = require('crypto').createHash('sha256').update('Hash me', 'utf8').digest('hex');
如果你想用 Python、PHP、Perl、Github 获得相同的哈希值:
const hash = require('crypto').createHash('sha256').update('Hash me', 'binary').digest('hex');
您还可以将'sha256'
替换为'sha1'
、'md5'
、'sha256'
、'sha512'
【讨论】:
嗨!我怎样才能反其道而行之?给定一个哈希和一个字符串,检查字符串是否等于哈希【参考方案7】:在这里,您可以在您的 node.js 版本支持的硬件上对所有支持的哈希进行基准测试。有些是加密的,有些只是用于校验和。它为每个算法计算了 100 万次“Hello World”。每个算法可能需要大约 1-15 秒(在标准 Google 计算引擎上使用 Node.js 4.2.2 测试)。
for(var i1=0;i1<crypto.getHashes().length;i1++)
var Algh=crypto.getHashes()[i1];
console.time(Algh);
for(var i2=0;i2<1000000;i2++)
crypto.createHash(Algh).update("Hello World").digest("hex");
console.timeEnd(Algh);
结果: DSA:1992 毫秒 DSA-SHA:1960 毫秒 DSA-SHA1:2062 毫秒 DSA-SHA1 旧版:2124 毫秒 RSA-MD4:1893 毫秒 RSA-MD5:1982 毫秒 RSA-MDC2:2797 毫秒 RSA-RIPEMD160:2101 毫秒 RSA-SHA:1948 毫秒 RSA-SHA1:1908 毫秒 RSA-SHA1-2:2042 毫秒 RSA-SHA224:2176 毫秒 RSA-SHA256:2158 毫秒 RSA-SHA384:2290 毫秒 RSA-SHA512:2357 毫秒 dsa 加密:1936 毫秒 dsaWithSHA:1910 毫秒 dsaWithSHA1:1926 毫秒 dss1:1928 毫秒 带有 SHA1 的 ecdsa:1880 毫秒 md4:1833ms md4WithRSAEncryption:1925 毫秒 md5:1863ms md5WithRSAEncryption:1923 毫秒 mdc2:2729 毫秒 mdc2WithRSA:2890 毫秒 成熟度:2101ms 成熟度 160:2153 毫秒 成熟 160WithRSA:2210 毫秒 rmd160:2146 毫秒 沙:1929ms sha1:1880 毫秒 sha1WithRSA 加密:1957 毫秒 sha224:2121ms sha224WithRSA 加密:2290 毫秒 sha256:2134 毫秒 sha256WithRSA 加密:2190 毫秒 sha384:2181 毫秒 sha384WithRSA 加密:2343 毫秒 sha512:2371 毫秒 sha512WithRSA 加密:2434 毫秒 shaWithRSA 加密:1966 毫秒 ssl2-md5:1853 毫秒 ssl3-md5:1868 毫秒 ssl3-sha1:1971 毫秒 漩涡:2578ms
【讨论】:
RSA-
前缀有什么作用?【参考方案8】:
我不得不扔掉我的 2 美分,希望这能帮助别人。
对于那些使用 CommonJS 的人
const crypto = require('crypto');
const secret = 'I love writing code, fixing things and building helpful tools';
const hash = crypto.createHmac('sha256', secret).digest('hex');
console.log('Hash successfully generated: ', hash);
对于那些使用 ES 模块的人
const createHmac = await import('crypto');
const secret = 'I love writing code, fixing things and building helpful tools';
const hash = createHmac('sha256', secret).digest('hex');
console.log('Hash successfully generated: ', hash);
超级简单! 快乐编码:)
【讨论】:
【参考方案9】:考虑到 http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/ (简而言之:先加密,然后验证。然后先验证,然后解密) 我在 node.js 中实现了以下解决方案:
function encrypt(text,password)
var cipher = crypto.createCipher(algorithm,password)
var crypted = cipher.update(text,'utf8','hex')
crypted += cipher.final('hex');
return crypted;
function decrypt(text,password)
var decipher = crypto.createDecipher(algorithm,password)
var dec = decipher.update(text,'hex','utf8')
dec += decipher.final('utf8');
return dec;
function hashText(text)
var hash = crypto.createHash('md5').update(text).digest("hex");
//console.log(hash);
return hash;
function encryptThenAuthenticate(plainText,pw)
var encryptedText = encrypt(plainText,pw);
var hash = hashText(encryptedText);
return encryptedText+"$"+hash;
function VerifyThenDecrypt(encryptedAndAuthenticatedText,pw)
var encryptedAndHashArray = encryptedAndAuthenticatedText.split("$");
var encrypted = encryptedAndHashArray[0];
var hash = encryptedAndHashArray[1];
var hash2Compare = hashText(encrypted);
if (hash === hash2Compare)
return decrypt(encrypted,pw);
可以通过以下方式进行测试:
var doom = encryptThenAuthenticate("The encrypted text",user.cryptoPassword);
console.log(VerifyThenDecrypt(doom,user.cryptoPassword));
希望这会有所帮助:-)
【讨论】:
【参考方案10】:我使用blueimp-md5,它是“与 Node.js 等服务器端环境、RequireJS、Browserify 或 webpack 等模块加载器以及所有 Web 浏览器兼容。”
像这样使用它:
var md5 = require("blueimp-md5");
var myHashedString = createHash('GreensterRox');
createHash(myString)
return md5(myString);
如果在公开场合传递散列值,最好对它们加盐,这样人们就更难重新创建它们:
createHash(myString)
var salt = 'HnasBzbxH9';
return md5(myString+salt);
【讨论】:
【参考方案11】:即使哈希不是出于安全考虑,您也可以使用 sha 代替 md5。在我看来,人们现在应该忘记 md5,它已成为过去!
不推荐使用普通的 nodejs sha256。所以,你现在有两种选择:
var shajs = require('sha.js') - https://www.npmjs.com/package/sha.js (used by Browserify)
var hash = require('hash.js') - https://github.com/indutny/hash.js
我更喜欢使用shajs
而不是hash
,因为我认为 sha 是当今最好的散列函数,你现在不需要不同的散列函数。因此,要获得一些十六进制哈希,您应该执行以下操作:
sha256.update('hello').digest('hex')
【讨论】:
感谢您编辑@marc_s。随意这样做。【参考方案12】:function md5(a)
var r = 0,
c = "";
return h(a);
function h(t)
return u(l(m(t)))
function l(t)
return p(g(f(t), 8 * t.length))
function u(t)
for (var e, i = r ? "0123456789ABCDEF" : "0123456789abcdef", n = "", o = 0; o < t.length; o++)
e = t.charCodeAt(o),
n += i.charAt(e >>> 4 & 15) + i.charAt(15 & e);
return n
function m(t)
for (var e, i, n = "", o = -1; ++o < t.length;)
e = t.charCodeAt(o),
i = o + 1 < t.length ? t.charCodeAt(o + 1) : 0,
55296 <= e && e <= 56319 && 56320 <= i && i <= 57343 && (e = 65536 + ((1023 & e) << 10) + (1023 & i),
o++),
e <= 127 ? n += String.fromCharCode(e) : e <= 2047 ? n += String.fromCharCode(192 | e >>> 6 & 31, 128 | 63 & e) : e <= 65535 ? n += String.fromCharCode(224 | e >>> 12 & 15, 128 | e >>> 6 & 63, 128 | 63 & e) : e <= 2097151 && (n += String.fromCharCode(240 | e >>> 18 & 7, 128 | e >>> 12 & 63, 128 | e >>> 6 & 63, 128 | 63 & e));
return n
function f(t)
for (var e = Array(t.length >> 2), i = 0; i < e.length; i++)
e[i] = 0;
for (i = 0; i < 8 * t.length; i += 8)
e[i >> 5] |= (255 & t.charCodeAt(i / 8)) << i % 32;
return e
function p(t)
for (var e = "", i = 0; i < 32 * t.length; i += 8)
e += String.fromCharCode(t[i >> 5] >>> i % 32 & 255);
return e
function g(t, e)
t[e >> 5] |= 128 << e % 32,
t[14 + (e + 64 >>> 9 << 4)] = e;
for (var i = 1732584193, n = -271733879, o = -1732584194, s = 271733878, a = 0; a < t.length; a += 16)
var r = i,
c = n,
h = o,
l = s;
n = E(n = E(n = E(n = E(n = N(n = N(n = N(n = N(n = C(n = C(n = C(n = C(n = S(n = S(n = S(n = S(n, o = S(o, s = S(s, i = S(i, n, o, s, t[a + 0], 7, -680876936), n, o, t[a + 1], 12, -389564586), i, n, t[a + 2], 17, 606105819), s, i, t[a + 3], 22, -1044525330), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 4], 7, -176418897), n, o, t[a + 5], 12, 1200080426), i, n, t[a + 6], 17, -1473231341), s, i, t[a + 7], 22, -45705983), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 8], 7, 1770035416), n, o, t[a + 9], 12, -1958414417), i, n, t[a + 10], 17, -42063), s, i, t[a + 11], 22, -1990404162), o = S(o, s = S(s, i = S(i, n, o, s, t[a + 12], 7, 1804603682), n, o, t[a + 13], 12, -40341101), i, n, t[a + 14], 17, -1502002290), s, i, t[a + 15], 22, 1236535329), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 1], 5, -165796510), n, o, t[a + 6], 9, -1069501632), i, n, t[a + 11], 14, 643717713), s, i, t[a + 0], 20, -373897302), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 5], 5, -701558691), n, o, t[a + 10], 9, 38016083), i, n, t[a + 15], 14, -660478335), s, i, t[a + 4], 20, -405537848), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 9], 5, 568446438), n, o, t[a + 14], 9, -1019803690), i, n, t[a + 3], 14, -187363961), s, i, t[a + 8], 20, 1163531501), o = C(o, s = C(s, i = C(i, n, o, s, t[a + 13], 5, -1444681467), n, o, t[a + 2], 9, -51403784), i, n, t[a + 7], 14, 1735328473), s, i, t[a + 12], 20, -1926607734), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 5], 4, -378558), n, o, t[a + 8], 11, -2022574463), i, n, t[a + 11], 16, 1839030562), s, i, t[a + 14], 23, -35309556), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 1], 4, -1530992060), n, o, t[a + 4], 11, 1272893353), i, n, t[a + 7], 16, -155497632), s, i, t[a + 10], 23, -1094730640), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 13], 4, 681279174), n, o, t[a + 0], 11, -358537222), i, n, t[a + 3], 16, -722521979), s, i, t[a + 6], 23, 76029189), o = N(o, s = N(s, i = N(i, n, o, s, t[a + 9], 4, -640364487), n, o, t[a + 12], 11, -421815835), i, n, t[a + 15], 16, 530742520), s, i, t[a + 2], 23, -995338651), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 0], 6, -198630844), n, o, t[a + 7], 10, 1126891415), i, n, t[a + 14], 15, -1416354905), s, i, t[a + 5], 21, -57434055), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 12], 6, 1700485571), n, o, t[a + 3], 10, -1894986606), i, n, t[a + 10], 15, -1051523), s, i, t[a + 1], 21, -2054922799), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 8], 6, 1873313359), n, o, t[a + 15], 10, -30611744), i, n, t[a + 6], 15, -1560198380), s, i, t[a + 13], 21, 1309151649), o = E(o, s = E(s, i = E(i, n, o, s, t[a + 4], 6, -145523070), n, o, t[a + 11], 10, -1120210379), i, n, t[a + 2], 15, 718787259), s, i, t[a + 9], 21, -343485551),
i = v(i, r),
n = v(n, c),
o = v(o, h),
s = v(s, l)
return [i, n, o, s]
function _(t, e, i, n, o, s)
return v((a = v(v(e, t), v(n, s))) << (r = o) | a >>> 32 - r, i);
var a, r
function S(t, e, i, n, o, s, a)
return _(e & i | ~e & n, t, e, o, s, a)
function C(t, e, i, n, o, s, a)
return _(e & n | i & ~n, t, e, o, s, a)
function N(t, e, i, n, o, s, a)
return _(e ^ i ^ n, t, e, o, s, a)
function E(t, e, i, n, o, s, a)
return _(i ^ (e | ~n), t, e, o, s, a)
function v(t, e)
var i = (65535 & t) + (65535 & e);
return (t >> 16) + (e >> 16) + (i >> 16) << 16 | 65535 & i
string = 'hello';
console.log(md5(string));
【讨论】:
【参考方案13】:你可以使用crypto-js加密标准的javaScript库,有最简单的方法来生成sha256
或sha512
const SHA256 = require("crypto-js/sha256");
const SHA512 = require("crypto-js/sha512");
let password = "hello"
let hash_256 = SHA256 (password).toString();
let hash_512 = SHA512 (password).toString();
【讨论】:
以上是关于node.js 哈希字符串?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JavaScript/Node.js 中生成 MD5 文件哈希?