diff --git a/scripts/solr_password.py b/scripts/solr_password.py new file mode 100755 index 000000000..7a558292d --- /dev/null +++ b/scripts/solr_password.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import secrets +import sys +from hashlib import sha256 +from base64 import b64encode, b64decode + +## +## Based on the logic here: +## https://www.planetcobalt.net/sdb/solr_password_hash.shtml +## http://www.mtitek.com/tutorials/solr/securing-solr-basic-auth.php +## https://github.com/apache/lucene-solr/blob/master/solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java +## +## Usage: +## python solr_passwod.py or python solr_password.py +## or yet: cat password.txt | xargs python solr_password.py +## + + +def solr_hash_password(password: str, salt: str = None) -> (str, str): + """ + Generates a password and salt to be used in Basic Auth Solr + + password: clean text password string + salt (optional): base64 salt string + returns: sha256 hash of password and salt (both base64 strings) + """ + m = sha256() + if salt is None: + salt = secrets.token_bytes(32) + else: + salt = b64decode(salt) + m.update(salt + password.encode('utf-8')) + digest = m.digest() + + m = sha256() + m.update(digest) + digest = m.digest() + + cypher = b64encode(digest).decode('utf-8') + salt = b64encode(salt).decode('utf-8') + return cypher, salt + + +def check_solr_hash(password: str, cypher: str, salt: str) -> bool: + m = sha256() + m.update(b64decode(salt) + password.encode('utf-8')) + digest = m.digest() + + m = sha256() + m.update(digest) + digest = m.digest() + + return b64encode(digest).decode('utf-8') == cypher + + +def test_hash_password(): + password = "SolrRocks" + salt = "Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=" + cypher = "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0=" + ret = solr_hash_password(password, salt) + assert ret[0] == cypher, "sha256 hashing of password failed!" + + cypher, salt = solr_hash_password(password) + assert solr_hash_password(password, salt) == (cypher, salt) + + +def test_hash_check(): + password = "SolrRocks" + salt = "Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=" + cypher = "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0=" + + assert check_solr_hash(password, cypher, salt), "Sha256 password check failed!" + + +if __name__ == '__main__': + if len(sys.argv) < 2 or len(sys.argv) > 3: + print('Usage: %s [salt_base64]' % sys.argv[0]) + sys.exit(0) + + if len(sys.argv) == 3: + _salt = sys.argv[2] + else: + _salt = None + print("%s %s" % solr_hash_password(sys.argv[1], _salt))