Невозможно создать один и тот же дайджест scrypt между реализациями Ruby-s и Go-s
У меня проблема с вычислением одного и того же дайджеста скрипта между RbNaCl и реализацией Go.
Вот как я генерирую ключ с помощью rbnacl:
opslimit = 2**20
memlimit = 2**24
digest_size = 32
digest = RbNaCl::PasswordHash.scrypt(
password,
salt,
opslimit,
memlimit,
digest_size
)
Значения параметров opslimit и memlimit были найдены в документации.
Вот моя попытка повторить те же результаты с Go:
N := 32768
r := 8
p := 1
keyLength := 32
secretKeyBytes, _ := scrypt.Key(password, salt, N, r, p, keyLength)
Значения для N, r, p и keyLength получены из документации.
пароль и соль имеют одинаковые значения.
Я не криптограф, но насколько я понимаю, должны быть одинаковые значения коэффициента стоимости, чтобы получить тот же дайджест? Проблема здесь в том, что, поскольку обе реализации принимают разное количество параметров, мне сложно найти и правильную комбинацию. Любые идеи, как сделать так, чтобы коэффициенты затрат соответствовали этим двум реализациям, чтобы я мог вычислять одинаковые хэши scrypt между двумя языками программирования?
1 ответ
Удалось вычислить N, p и r из opslimit и memlimit, посмотрев на функцию- указатель libsodium, которая была вызвана crypto_pwhash_scryptsalsa208sha256, которая, в свою очередь, была вызвана реализацией scrypt Руби в RbNaCl.
Вот соответствующий код для преобразования opslimit и memlimit в соответствующие N, p и r, которые будут использоваться другими реализациями scrypt, которые предлагают API более низкого уровня для scrypt, если кому-то еще это понадобится в будущем: https://gist.github.com/jarmo/22f871076ff70e39b54e69c6305c020f
Просто измените значения переменных opslimit и memlimit в main, скомпилируйте их с помощью gcc и запустите, чтобы получить значения для N, r и p.
В целом проблема заключалась в том, что Go предоставляет API более низкого уровня, чем RbNaCl, даже если они делают то же самое.