Enable BCRYPTHashingScheme for Plone userpasswords

only for documentation, if bcrypt algorithm for passwords is needed:

pip install bcrypt

add the following code to your custom package in the __init__.py and override the pw_encrypt method

from AuthEncoding import AuthEncoding
from AuthEncoding.compat import to_bytes
from AuthEncoding.compat import to_string

def pw_encrypt(pw, encoding="SSHA"):
    # see AuthEncoding
    # https://github.com/zopefoundation/AuthEncoding/blob/45f5a97105058f368b3bc700e6aee17b72b5c444/src/AuthEncoding/AuthEncoding.py#L186
    
    # set BCRYPT,  if installed and encoding is SSHA
    if encoding == "SSHA" and AuthEncoding.bcrypt:
        encoding = "BCRYPT"

    """Encrypt the provided plain text password using the encoding if provided
    and return it in an LDAP-style representation."""
    encoding = to_string(encoding)
    for id, prefix, scheme in AuthEncoding._getSortedSchemes():
        if encoding == id:
            return to_bytes(prefix) + scheme.encrypt(pw)
    raise ValueError("Not supported: %s" % encoding)

# patch the method with your custom pw_encrypt
AuthEncoding.pw_encrypt = pw_encrypt

and the test

def test_user_password(self):
    user = api.user.create(
        username='noob',
        email='noob@plone.org',
        password='secretpw',
    )
    hash_map = self.portal.acl_users.source_users._user_passwords
    hash = hash_map.get(user.id, '').decode()
    self.assertTrue("{BCRYPT}" in hash)

or has anyone another cleaner solution?

2 Likes