Node Crypto 和 macOS sha256sum 之间的 SHA 哈希值不匹配
SHA Hashes Don't Match between Node Crypto and macOS sha256sum
我正在从 node.js 中的 Internet 源获取一个大的 gzip 压缩 JSON 文件。该来源还提供了一个包含 SHA256 哈希的元文件。如果我将文件写入磁盘并对生成的文件求和,则哈希匹配;但是,当在 NodeJS 中对缓冲区求和时,哈希值不匹配。
const https = require('request-promise-native');
const request = require('request');
const zlib = require('zlib');
const crypto = require('crypto');
const getList = async (list) => {
// Start by getting meta file to SHA result
const meta = await https(`https://example.com/${list}.meta`);
const metaHash = meta.match(/sha256:(.+)$/im)[1].toLowerCase();
// metaHash = "f36c4c75f1293b3d3415145d78a1ffc1b8b063b083f9854e471a3888f77353e1"
// Download and unzip whole file
const chunks = [];
const file = await new Promise((resolve, reject) => {
const stream = request(`https://example.com/${list}.json.gz`);
stream.on('data', chunk => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => {
const buffer = Buffer.concat(chunks);
// Unzip
zlib.gunzip(buffer, (error, unBuffer) => {
// TEST: Write to disk
fs.writeFile('/tmp/test.json', unBuffer);
// Check SHA hash
const afterHash = crypto.createHash('sha256');
afterHash.update(unBuffer);
const hash = afterHash.digest('hex');
// hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
// metaHash =/= hash
if (metaHash === hash) resolve(unBuffer.toString());
else {
// reject(`SHA hashes do not match for ${list}`);
console.log(`${list}\n${metaHash}\n${hash}`);
}
});
});
});
};
但是从我的 macOS 终端,它匹配:
$ sha256sum /tmp/test.json
f36c4c75f1293b3d3415145d78a1ffc1b8b063b083f9854e471a3888f77353e1 /tmp/test.json
这让我相信文件已正确下载和解压缩。我是否错误地实施了 node.js 加密?我做错了什么吗?谢谢!
更新
我刚刚意识到我尝试的每个文件都从 crypto
得到相同的散列 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
,所以我肯定在这里做错了......
您的 e3b0c...
是空序列的 SHA-256,即零输入字节。
我从来没有弄清楚我做错了什么。我改用了 hasha,这解决了问题。
const hasha = require('hasha');
...
// Unzip
zlib.gunzip(buffer, (error, unBuffer) => {
// Check SHA hash
const hash = hasha(unBuffer, { algorithm: 'sha256' });
if (metaHash === hash) resolve(unBuffer.toString());
else reject(`SHA hashes do not match for ${list}`);
});
我正在从 node.js 中的 Internet 源获取一个大的 gzip 压缩 JSON 文件。该来源还提供了一个包含 SHA256 哈希的元文件。如果我将文件写入磁盘并对生成的文件求和,则哈希匹配;但是,当在 NodeJS 中对缓冲区求和时,哈希值不匹配。
const https = require('request-promise-native');
const request = require('request');
const zlib = require('zlib');
const crypto = require('crypto');
const getList = async (list) => {
// Start by getting meta file to SHA result
const meta = await https(`https://example.com/${list}.meta`);
const metaHash = meta.match(/sha256:(.+)$/im)[1].toLowerCase();
// metaHash = "f36c4c75f1293b3d3415145d78a1ffc1b8b063b083f9854e471a3888f77353e1"
// Download and unzip whole file
const chunks = [];
const file = await new Promise((resolve, reject) => {
const stream = request(`https://example.com/${list}.json.gz`);
stream.on('data', chunk => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => {
const buffer = Buffer.concat(chunks);
// Unzip
zlib.gunzip(buffer, (error, unBuffer) => {
// TEST: Write to disk
fs.writeFile('/tmp/test.json', unBuffer);
// Check SHA hash
const afterHash = crypto.createHash('sha256');
afterHash.update(unBuffer);
const hash = afterHash.digest('hex');
// hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
// metaHash =/= hash
if (metaHash === hash) resolve(unBuffer.toString());
else {
// reject(`SHA hashes do not match for ${list}`);
console.log(`${list}\n${metaHash}\n${hash}`);
}
});
});
});
};
但是从我的 macOS 终端,它匹配:
$ sha256sum /tmp/test.json
f36c4c75f1293b3d3415145d78a1ffc1b8b063b083f9854e471a3888f77353e1 /tmp/test.json
这让我相信文件已正确下载和解压缩。我是否错误地实施了 node.js 加密?我做错了什么吗?谢谢!
更新
我刚刚意识到我尝试的每个文件都从 crypto
得到相同的散列 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
,所以我肯定在这里做错了......
您的 e3b0c...
是空序列的 SHA-256,即零输入字节。
我从来没有弄清楚我做错了什么。我改用了 hasha,这解决了问题。
const hasha = require('hasha');
...
// Unzip
zlib.gunzip(buffer, (error, unBuffer) => {
// Check SHA hash
const hash = hasha(unBuffer, { algorithm: 'sha256' });
if (metaHash === hash) resolve(unBuffer.toString());
else reject(`SHA hashes do not match for ${list}`);
});