##// END OF EJS Templates
Add hashed passphrase generation and verification.
Stefan van der Walt -
Show More
@@ -0,0 +1,79 b''
1 """
2 Password generation for the IPython notebook.
3 """
4
5 import hashlib
6 import random
7
8 def passwd(passphrase):
9 """Generate hashed password and salt for use in notebook configuration.
10
11 Parameters
12 ----------
13 passphrase : str
14 Password to hash.
15
16 Returns
17 -------
18 hashed_passphrase : str
19 Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.
20
21 Examples
22 --------
23 In [1]: passwd('mypassword')
24 Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'
25
26 """
27 algorithm = 'sha1'
28
29 h = hashlib.new(algorithm)
30 salt = hex(int(random.getrandbits(16)))[2:]
31 h.update(passphrase + salt)
32
33 return ':'.join((algorithm, salt, h.hexdigest()))
34
35 def passwd_check(hashed_passphrase, passphrase):
36 """Verify that a given passphrase matches its hashed version.
37
38 Parameters
39 ----------
40 hashed_passphrase : str
41 Hashed password, in the format returned by `passwd`.
42 passphrase : str
43 Passphrase to validate.
44
45 Returns
46 -------
47 valid : bool
48 True if the passphrase matches the hash.
49
50 Examples
51 --------
52 In [1]: from IPython.lib.security import passwd_check
53
54 In [2]: passwd_check('sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12',
55 ...: 'mypassword')
56 Out[2]: True
57
58 In [3]: passwd_check('sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12',
59 ...: 'anotherpassword')
60 Out[3]: False
61
62 """
63 # Algorithm and hash length
64 supported_algorithms = {'sha1': 40}
65
66 try:
67 algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
68 except (ValueError, TypeError):
69 return False
70
71 if not (algorithm in supported_algorithms and \
72 len(pw_digest) == supported_algorithms[algorithm] and \
73 len(salt) == 4):
74 return False
75
76 h = hashlib.new(algorithm)
77 h.update(passphrase + salt)
78
79 return h.hexdigest() == pw_digest
@@ -0,0 +1,21 b''
1 from IPython.lib import passwd
2 from IPython.lib.security import passwd_check
3 import nose.tools as nt
4
5 def test_passwd_structure():
6 p = passwd('passphrase')
7 algorithm, salt, hashed = p.split(':')
8 nt.assert_equals(algorithm, 'sha1')
9 nt.assert_equals(len(salt), 4)
10 nt.assert_equals(len(hashed), 40)
11
12 def test_roundtrip():
13 p = passwd('passphrase')
14 nt.assert_equals(passwd_check(p, 'passphrase'), True)
15
16 def test_bad():
17 p = passwd('passphrase')
18 nt.assert_equals(passwd_check(p, p), False)
19 nt.assert_equals(passwd_check(p, 'a:b:c:d'), False)
20 nt.assert_equals(passwd_check(p, 'a:b'), False)
21
@@ -25,6 +25,8 b' from IPython.lib.inputhook import ('
25 current_gui
25 current_gui
26 )
26 )
27
27
28 from IPython.lib.security import passwd
29
28 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
29 # Code
31 # Code
30 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
General Comments 0
You need to be logged in to leave comments. Login now