21 |
21 |
|
22 |
22 |
|
23 |
23 |
def base64url_encode(raw):
|
24 |
|
return base64.urlsafe_b64encode(raw).rstrip('=')
|
|
24 |
return base64.urlsafe_b64encode(raw).rstrip(b'=')
|
25 |
25 |
|
26 |
26 |
|
27 |
27 |
def get_hashclass(name):
|
... | ... | |
64 |
64 |
def add_padding(msg, block_size):
|
65 |
65 |
'''Pad message with zero bytes to match block_size'''
|
66 |
66 |
pad_length = block_size - (len(msg) + 2) % block_size
|
67 |
|
padded = struct.pack('<h%ds%ds' % (len(msg), pad_length), len(msg), msg, '\0' * pad_length)
|
|
67 |
padded = struct.pack(b'<h%ds%ds' % (len(msg), pad_length), len(msg), msg, b'\0' * pad_length)
|
68 |
68 |
assert len(padded) % block_size == 0
|
69 |
69 |
return padded
|
70 |
70 |
|
71 |
71 |
|
72 |
72 |
def remove_padding(msg, block_size):
|
73 |
73 |
'''Ignore padded zero bytes'''
|
|
74 |
import six
|
|
75 |
|
74 |
76 |
try:
|
75 |
|
msg_length, = struct.unpack('<h', msg[:2])
|
|
77 |
msg_length, = struct.unpack(b'<h', msg[:2])
|
76 |
78 |
except struct.error:
|
77 |
79 |
raise DecryptionError('wrong padding')
|
78 |
80 |
if len(msg) % block_size != 0:
|
... | ... | |
81 |
83 |
unpadded = msg[2:2 + msg_length]
|
82 |
84 |
if msg_length > len(msg) - 2:
|
83 |
85 |
raise DecryptionError('wrong padding')
|
84 |
|
if not all(c == '\0' for c in msg[2 + msg_length:]):
|
|
86 |
|
|
87 |
padded_zero = '\x00' if six.PY2 else 0
|
|
88 |
if not all(c == padded_zero for c in msg[2 + msg_length:]):
|
85 |
89 |
raise DecryptionError('padding is not all zero')
|
86 |
90 |
if len(unpadded) != msg_length:
|
87 |
91 |
raise DecryptionError('wrong padding')
|
... | ... | |
99 |
103 |
key_size = 16
|
100 |
104 |
hmac_size = key_size
|
101 |
105 |
|
102 |
|
iv = hashmod.new(salt).digest()
|
|
106 |
iv = hashmod.new(salt.encode('utf-8')).digest()
|
103 |
107 |
|
104 |
108 |
prf = lambda secret, salt: HMAC.new(secret, salt, hashmod).digest()
|
105 |
109 |
|
... | ... | |
113 |
117 |
|
114 |
118 |
hmac = prf(key, crypted)[:hmac_size]
|
115 |
119 |
|
116 |
|
raw = struct.pack('<2sBH', 'a2', mode, count) + crypted + hmac
|
|
120 |
raw = struct.pack(b'<2sBH', b'a2', mode, count) + crypted + hmac
|
117 |
121 |
return base64url_encode(raw)
|
118 |
122 |
|
119 |
123 |
|
... | ... | |
133 |
137 |
magic, mode, count = struct.unpack('<2sBH', raw[:5])
|
134 |
138 |
except struct.error as e:
|
135 |
139 |
raise DecryptionError('invalid packing', e)
|
136 |
|
if magic != 'a2':
|
|
140 |
if magic != b'a2':
|
137 |
141 |
raise DecryptionError('invalid magic string', magic)
|
138 |
142 |
if mode != 1:
|
139 |
143 |
raise DecryptionError('mode is not AES128-SHA256', mode)
|
... | ... | |
145 |
149 |
if not crypted or not hmac or prf(key, crypted)[:hmac_size] != hmac:
|
146 |
150 |
raise DecryptionError('invalid HMAC')
|
147 |
151 |
|
148 |
|
iv = hashmod.new(salt).digest()
|
|
152 |
iv = hashmod.new(salt.encode('utf-8')).digest()
|
149 |
153 |
|
150 |
154 |
aes_key = PBKDF2(key, iv, dkLen=key_size, count=count, prf=prf)
|
151 |
155 |
|
152 |
|
-
|