2424from base64 import b64encode , b64decode
2525from hashlib import md5 , sha1
2626
27- from roundup .anypy .strings import us2s , s2b
27+ from roundup .anypy .strings import us2s , b2s , s2b
2828
2929try :
3030 import crypt
3131except ImportError :
3232 crypt = None
3333
34- _bempty = ""
34+ _bempty = b ""
3535_bjoin = _bempty .join
3636
37+ def bchr (c ):
38+ if bytes == str :
39+ # Python 2.
40+ return chr (c )
41+ else :
42+ # Python 3.
43+ return bytes ((c ,))
44+
45+ def bord (c ):
46+ if bytes == str :
47+ # Python 2.
48+ return ord (c )
49+ else :
50+ # Python 3. Elements of bytes are integers.
51+ return c
52+
3753def getrandbytes (count ):
38- return _bjoin (chr (random .randint (0 ,255 )) for i in range (count ))
54+ return _bjoin (bchr (random .randint (0 ,255 )) for i in range (count ))
3955
4056#NOTE: PBKDF2 hash is using this variant of base64 to minimize encoding size,
4157# and have charset that's compatible w/ unix crypt variants
4258def h64encode (data ):
4359 """encode using variant of base64"""
44- return b64encode (data , "./" ).strip ("=\n " )
60+ return b2s ( b64encode (data , b "./" ).strip (b "=\n ") )
4561
4662def h64decode (data ):
4763 """decode using variant of base64"""
64+ data = s2b (data )
4865 off = len (data ) % 4
4966 if off == 0 :
50- return b64decode (data , "./" )
67+ return b64decode (data , b "./" )
5168 elif off == 1 :
5269 raise ValueError ("Invalid base64 input" )
5370 elif off == 2 :
54- return b64decode (data + "==" , "./" )
71+ return b64decode (data + b "==" , b "./" )
5572 else :
56- return b64decode (data + "=" , "./" )
73+ return b64decode (data + b "=" , b "./" )
5774
5875try :
5976 from M2Crypto .EVP import pbkdf2 as _pbkdf2
@@ -64,7 +81,7 @@ def h64decode(data):
6481
6582 def xor_bytes (left , right ):
6683 "perform bitwise-xor of two byte-strings"
67- return _bjoin (chr ( ord (l ) ^ ord (r )) for l , r in zip (left , right ))
84+ return _bjoin (bchr ( bord (l ) ^ bord (r )) for l , r in zip (left , right ))
6885
6986 def _pbkdf2 (password , salt , rounds , keylen ):
7087 digest_size = 20 # sha1 generates 20-byte blocks
@@ -98,7 +115,7 @@ def pbkdf2(password, salt, rounds, keylen):
98115 """pkcs#5 password-based key derivation v2.0
99116
100117 :arg password: passphrase to use to generate key (if unicode, converted to utf-8)
101- :arg salt: salt string to use when generating key (if unicode, converted to utf-8)
118+ :arg salt: salt bytes to use when generating key
102119 :param rounds: number of rounds to use to generate key
103120 :arg keylen: number of bytes to generate
104121
@@ -108,7 +125,6 @@ def pbkdf2(password, salt, rounds, keylen):
108125 raw bytes of generated key
109126 """
110127 password = s2b (us2s (password ))
111- salt = s2b (us2s (salt ))
112128 if keylen > 40 :
113129 #NOTE: pbkdf2 allows up to (2**31-1)*20 bytes,
114130 # but m2crypto has issues on some platforms above 40,
@@ -351,7 +367,7 @@ def test():
351367
352368 # PBKDF2 - low level function
353369 from binascii import unhexlify
354- k = pbkdf2 ("password" , "ATHENA.MIT.EDUraeburn" , 1200 , 32 )
370+ k = pbkdf2 ("password" , b "ATHENA.MIT.EDUraeburn" , 1200 , 32 )
355371 assert k == unhexlify ("5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13" )
356372
357373 # PBKDF2 - hash function
0 commit comments