Разница между хэшированием в Javascript и Python - PullRequest
3 голосов
/ 11 февраля 2020

(есть довольно много довольно похожих постов - я их читал, решения в большинстве своем, похоже, заключаются в Python строковом кодировании, которое, как я думал, контролировалось, но явно все еще нет)

Я пытаюсь портировать пакет NPM на Python, но я не могу получить одинаковые результаты для каждого сценария. Я сократил это до:

import sys
import hashlib
from binascii import hexlify
print("Python", sys.version)

test1 = "abcdefg".encode("utf-8")
print(hexlify(test1), hashlib.sha256(test1).hexdigest())
test2 = "abcdefg".encode("latin1")
print(hexlify(test2), hashlib.sha256(test2).hexdigest())
test3 = "abcdefg".encode("ascii")
print(hexlify(test3), hashlib.sha256(test3).hexdigest())
test4 = b"abcdefg"
print(hexlify(test4), hashlib.sha256(test4).hexdigest())
test5 = bytes([0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67])
print(hexlify(test5), hashlib.sha256(test5).hexdigest())
var js_sha3 = require('js-sha3')
var crypto = require('crypto');
var buffer = require('buffer');
console.log("Javascript:", process.version)

function toHex(str) {
  return new Buffer.from(str).toString('hex')
}

var test1 = "abcdefg"
console.log(toHex(test1).toString('hex'), js_sha3.sha3_256(test1))
var test2 = Buffer.from("abcdefg")
console.log(toHex(test2), js_sha3.sha3_256(test2))
var test3 = "abcdefg"
console.log(toHex(test3), crypto.createHash('sha3-256').update(test3).digest("hex"))
var test4 = Buffer.from("abcdefg")
console.log(toHex(test4), crypto.createHash('sha3-256').update(test4).digest("hex"))
var test5 = buffer.Buffer.from("abcdefg", 'hex')
console.log(toHex(test5), js_sha3.sha3_256(test5))

Однако, вывод выглядит так:

Python 3.7.4 (default, Sep  7 2019, 18:27:02) 
[Clang 10.0.1 (clang-1001.0.46.4)]
b'61626364656667' 7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
b'61626364656667' 7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
b'61626364656667' 7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
b'61626364656667' 7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
b'61626364656667' 7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
Javascript: v12.15.0
61626364656667 7d55114476dfc6a2fbeaa10e221a8d0f32fc8f2efb69a6e878f4633366917a62
61626364656667 7d55114476dfc6a2fbeaa10e221a8d0f32fc8f2efb69a6e878f4633366917a62
61626364656667 7d55114476dfc6a2fbeaa10e221a8d0f32fc8f2efb69a6e878f4633366917a62
61626364656667 7d55114476dfc6a2fbeaa10e221a8d0f32fc8f2efb69a6e878f4633366917a62
abcdef 8b8a2a6bc589cd378fc57f47d5668c58b31167b2bf9e632696e5c2d50fc16002

Однако, введя abcdefg в https://emn178.github.io/online-tools/sha256.html * (который поддерживается js-sha3) возвращает 7d1a54....

Итак, мой вопрос - как отличается использование SHA-256 в Javascript и Python? Что мне не хватает? (Я не буду пытаться утверждать, что одна из реализаций не работает!)

[править] Если я использую MD5 вместо SHA-256, результаты совпадают, что еще больше увеличивает загадку!

x = bytes("thequickbrownfox", "utf-8")
print(hashlib.md5(x).hexdigest())
print(hashlib.sha256(x).hexdigest())
var x = "thequickbrownfox"
console.log(crypto.createHash('md5').update(x).digest("hex"))
console.log(crypto.createHash('sha3-256').update(x).digest("hex"))

выходы:

308fb76dc4d730360ee33932d2fb1056
bd484b82d7875e115c7273e9c6102ca4946b7c55fe905012be9152b87fe09568
308fb76dc4d730360ee33932d2fb1056
4822316e0d7a7a2ce1bb6489e57c73ca5db4c7c660c79c3c65839bd4aaf4ef10

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Это, безусловно, правильно, что для одного и того же ввода функция ha sh производит один и тот же дайджест. Тем не менее, тут возникает сложность: многие из этих функций ha sh принимают входные данные в виде байтов. Это означает, что здесь кодирование строки выдачи в разные зависит от платформы. Тем не менее, вы также должны принять во внимание, что разные языки программирования могут иметь небольшие различия, например, я не знаком с python, но это может быть добавление пустого пространства в конце ввода и / или использование другого Unicode представления для различных специальных символов. Даже одно байтовое изменение на входе приведет к совершенно другому выходу, как и следовало ожидать от функции ha sh.

Подводя итог, если вы хотите выяснить, почему другой ha sh создано, вы должны выполнить двоичное сравнение ввода функций ha sh. Или распечатайте ввод для SHA-256 в шестнадцатеричном формате или в формате 64.

0 голосов
/ 12 февраля 2020

Сегодня я узнал очень важную разницу между sha256 и sha3-256.

...