#python #linux #hash #openssl #pbkdf2
#python #linux #хэш #openssl #pbkdf2
Вопрос:
Я обнаружил, что mkpasswd и openssl passwd (с одной стороны) не выдают тот же «производный ключ», что и python hashlib.pbkdf2_hmac() и mbedtls.pbkdf2 (с другой стороны), хотя оба утверждают, что реализуют один и тот же стандарт (PBKDF2).
Я пытаюсь вычислить хэши паролей Linux во встроенной системе. Я использую библиотеку mbedtls, которая имеет функцию: mbedtls_pkcs5_pbkdf2_hmac()
. С теми же параметрами: SHA256, 5000 раундов, ‘TestPasswort’ и ‘SALTsaltSALTsalt’ я могу воспроизвести результат с помощью pythons hashlib:
$ python3
>>> import hashlib
>>> dk = hashlib.pbkdf2_hmac('sha256', b'TestPasswort' , b'SALTsaltSALTsalt', 5000)
>>> dk.hex()
'c27f613f2c4515136f5741a6b80f2fd05c4e3070ab03cb588be842afff6263fe'
В качестве второго шага я запускаю результат (32 байта) через модифицированный кодировщик base64 (см. Ссылку ниже).
Конечный результат:
kbxVDml33FBjJo4ai.wjo3lCA50f.whMWyV0fzxWMzs
С другой стороны, mkpasswd и openssl выдают разные результаты (но согласуются между собой):
mkpasswd -m sha-256 -R 5000 --salt=SALTsaltSALTsalt TestPasswort
$5$rounds=5000$SALTsaltSALTsalt$NEAgjfoV3kysMtvGP0sS8D0LU9hZlXRnx/g4zn7QPb/
openssl passwd -5 --salt=SALTsaltSALTsalt TestPasswort
$5$SALTsaltSALTsalt$NEAgjfoV3kysMtvGP0sS8D0LU9hZlXRnx/g4zn7QPb/
Однако:
kbxVDml33FBjJo4ai.wjo3lCA50f.whMWyV0fzxWMzs
и:
NEAgjfoV3kysMtvGP0sS8D0LU9hZlXRnx/g4zn7QPb/
явно разные.
Я делаю здесь простую ошибку? Как я могу заставить python hashlib.pbkdf2 и openssl passwd выдавать один и тот же результат или, по крайней мере, сопоставлять их?
————для ссылки мой модифицированный кодировщик base64:——————-
#!/bin/python3
ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz'
ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digits = '0123456789'
##note the difference to base64 here:
base64_alphabet = './' digits ascii_uppercase ascii_lowercase
to_encode = input("base64 encoder -> ")
chunks_8bit = ''
for bits in to_encode :
y = int(bits,16)
chunks_8bit = chunks_8bit format(y,'04b')
chunks_6bit = [chunks_8bit[bits:bits 6] for bits in range(0,len(chunks_8bit),6)]
padding_amount = ( 6 - len(chunks_6bit[len(chunks_6bit)-1]) )
chunks_6bit[len(chunks_6bit)-1] = padding_amount * '0'
encoded = ''.join([base64_alphabet[int(bits,2)] for bits in chunks_6bit])
print('Base64 encoded version of {to_encode} is: {result}'.format(to_encode = to_encode, result = encoded))`
Ответ №1:
Я сам нашел ответ: openssl passwd и mkpasswd не реализуют PBKDF2, но: sha-crypt; см., Например, Здесь: https://code.woboq.org/userspace/glibc/crypt/sha256-crypt.c.html и вот здесь: https://www.akkadia.org/drepper/SHA-crypt.txt
Базовый алгоритм тот же, т.Е. Повторное применение хэш-функции, например, sha-256. Поэтому я был введен в заблуждение, полагая, что sha256-crypt будет реализовывать PBKDF2 с sha256 в качестве хэш-функции.