Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

46 wiersze
1.6KB

  1. #!/bin/python
  2. import os
  3. import argparse
  4. from hashlib import sha256
  5. from base64 import b64encode, b64decode
  6. from binascii import hexlify
  7. def generate_hash(password, salt=None):
  8. if salt is None:
  9. salt = os.urandom(4)
  10. salted = salt + password.encode('utf-8')
  11. hashed = salt + sha256(salted).digest()
  12. return b64encode(hashed).decode('utf-8')
  13. def test_hash(hashed, password, expected_salt=None):
  14. hash_bytes = b64decode(hashed)
  15. salt = hash_bytes[0:4]
  16. if expected_salt is not None and salt != expected_salt:
  17. return f'Hash {hexlify(hash_bytes)} with salt {hexlify(salt)} does not match expected salt {hexlify(expected_salt)}'
  18. if generate_hash(password, salt) == hashed:
  19. return f'Password matches hash'
  20. else:
  21. return f'Password does not match hash'
  22. if __name__ == '__main__':
  23. parser = argparse.ArgumentParser(description='Tool for hashing user passwords that can be added in RabbitMQ config files.')
  24. parser.add_argument('password', type=str, help='The password to hash or test against')
  25. parser.add_argument('-s', '--salt', dest='salt', type=str, help='Use a given salt instead of generatinga random one. If used with the --test argument, it verifies that the hash used this salt')
  26. parser.add_argument('-t', '--test', metavar='HASH', dest='test', type=str, help='Instead of hashing a password, check if a password matches a hash')
  27. args = parser.parse_args()
  28. if args.salt:
  29. salt = bytes.fromhex(args.salt)
  30. else:
  31. salt = None
  32. if args.test:
  33. print(test_hash(args.test, args.password, salt))
  34. else:
  35. print(generate_hash(args.password, salt))