Skip to content

Commit 8ae376b

Browse files
committed
Repair make_hash on Python 3.
1 parent 7711890 commit 8ae376b

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

mig/shared/pwcrypto.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from builtins import zip, range
3636
from base64 import b64encode, b64decode, b16encode, b16decode, \
3737
urlsafe_b64encode, urlsafe_b64decode
38+
import codecs
3839
from os import urandom
3940
from random import SystemRandom
4041
from string import ascii_lowercase, ascii_uppercase, digits
@@ -114,12 +115,14 @@ def best_crypt_salt(configuration):
114115
return salt_data
115116

116117

117-
def make_hash(password):
118+
def make_hash(password, _urandom=urandom):
118119
"""Generate a random salt and return a new hash for the password."""
119-
salt = b64encode(urandom(SALT_LENGTH))
120-
derived = b64encode(hashlib.pbkdf2_hmac(HASH_FUNCTION,
121-
force_utf8(password), salt,
122-
COST_FACTOR, KEY_LENGTH))
120+
salt = b64encode(_urandom(SALT_LENGTH))
121+
password_bytes = codecs.encode(password, 'utf8')
122+
password_hashed = hashlib.pbkdf2_hmac(HASH_FUNCTION,
123+
password_bytes, salt,
124+
COST_FACTOR, KEY_LENGTH)
125+
derived = b64encode(password_hashed)
123126
return 'PBKDF2${}${}${}${}'.format(HASH_FUNCTION, COST_FACTOR,
124127
salt, derived)
125128

tests/test_mig_shared_pwcrypto.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# --- BEGIN_HEADER ---
4+
#
5+
# Copyright (C) 2003-2024 The MiG Project by the Science HPC Center at UCPH
6+
#
7+
# This file is part of MiG.
8+
#
9+
# MiG is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation; either version 2 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# MiG is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program; if not, write to the Free Software
21+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22+
# USA.
23+
#
24+
# --- END_HEADER ---
25+
#
26+
27+
"""Unit test pwcrypto functions"""
28+
29+
import os
30+
import sys
31+
32+
sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), ".")))
33+
34+
from support import PY2, MigTestCase, temppath, testmain
35+
from mig.shared.pwcrypto import *
36+
37+
class MigSharedPwcrypto_make_hash(MigTestCase):
38+
def test_pickle_string(self):
39+
expected_py2 = "PBKDF2$sha256$10000$MDAwMDAwMDAwMDAw$epib2rEg/HYTQZFnCp7hmIGZ6rzHnViy"
40+
expected_py3 = "PBKDF2$sha256$10000$b'MDAwMDAwMDAwMDAw'$b'epib2rEg/HYTQZFnCp7hmIGZ6rzHnViy'"
41+
expected = expected_py2 if PY2 else expected_py3
42+
43+
actual = make_hash('foobar', _urandom=lambda vlen: b'0' * vlen)
44+
45+
self.assertEqual(actual, expected, "mismatch pickling string")
46+
47+
48+
if __name__ == '__main__':
49+
testmain()

0 commit comments

Comments
 (0)