diff options
author | Mike Crute <mike@crute.us> | 2017-10-01 01:28:24 +0000 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2017-10-01 01:28:24 +0000 |
commit | dd19641addd9537a11552def63a4438fa9aac1c8 (patch) | |
tree | 10d8cb874b1061219865415d56e3aade7559d4f2 | |
parent | 5ba28244b68fcb8b375a86046545b7bd352050e4 (diff) | |
download | pydora-dd19641addd9537a11552def63a4438fa9aac1c8.tar.bz2 pydora-dd19641addd9537a11552def63a4438fa9aac1c8.tar.xz pydora-dd19641addd9537a11552def63a4438fa9aac1c8.zip |
Add pure-python blowfish backend
-rw-r--r-- | pandora/transport.py | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/pandora/transport.py b/pandora/transport.py index 6693824..c3fc71c 100644 --- a/pandora/transport.py +++ b/pandora/transport.py | |||
@@ -15,10 +15,6 @@ import json | |||
15 | import base64 | 15 | import base64 |
16 | import requests | 16 | import requests |
17 | from requests.adapters import HTTPAdapter | 17 | from requests.adapters import HTTPAdapter |
18 | from cryptography.hazmat.backends import default_backend | ||
19 | from cryptography.hazmat.primitives.ciphers import Cipher | ||
20 | from cryptography.hazmat.primitives.ciphers.modes import ECB | ||
21 | from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish | ||
22 | 18 | ||
23 | from .errors import PandoraException | 19 | from .errors import PandoraException |
24 | 20 | ||
@@ -245,17 +241,16 @@ class BlowfishCryptor(object): | |||
245 | Handles symmetric Blowfish cryptography of raw byte messages with or | 241 | Handles symmetric Blowfish cryptography of raw byte messages with or |
246 | without padding. Does not handle messages that are encoded in other formats | 242 | without padding. Does not handle messages that are encoded in other formats |
247 | like hex or base64. | 243 | like hex or base64. |
244 | |||
245 | Subclasses implement the cryptography based on different back-end | ||
246 | libraries. | ||
248 | """ | 247 | """ |
249 | 248 | ||
250 | def __init__(self, key): | 249 | block_size = 8 |
251 | self.cipher = Cipher( | ||
252 | Blowfish(key.encode("ascii")), ECB(), backend=default_backend()) | ||
253 | 250 | ||
254 | @staticmethod | 251 | def _add_padding(self, data): |
255 | def _add_padding(data): | 252 | pad_size = self.block_size - (len(data) % self.block_size) |
256 | block_size = Blowfish.block_size | 253 | padding = (chr(pad_size) * pad_size).encode("ascii") |
257 | pad_size = len(data) % block_size | ||
258 | padding = (chr(pad_size) * (block_size - pad_size)).encode("ascii") | ||
259 | return data.encode("utf-8") + padding | 254 | return data.encode("utf-8") + padding |
260 | 255 | ||
261 | @staticmethod | 256 | @staticmethod |
@@ -265,9 +260,25 @@ class BlowfishCryptor(object): | |||
265 | raise ValueError('Invalid padding') | 260 | raise ValueError('Invalid padding') |
266 | return data[:-pad_size] | 261 | return data[:-pad_size] |
267 | 262 | ||
268 | @staticmethod | 263 | |
269 | def _make_bytearray(data): | 264 | class CryptographyBlowfish(BlowfishCryptor): |
270 | return bytearray(len(data) + (Blowfish.block_size - 1)) | 265 | """Cryptography Blowfish Cryptor |
266 | |||
267 | Uses the python cryptography library which wraps OpenSSL. Compatible with | ||
268 | both Python 2 and 3 but requires a native dependency. | ||
269 | """ | ||
270 | |||
271 | def __init__(self, key): | ||
272 | from cryptography.hazmat.backends import default_backend | ||
273 | from cryptography.hazmat.primitives.ciphers import Cipher | ||
274 | from cryptography.hazmat.primitives.ciphers.modes import ECB | ||
275 | from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish | ||
276 | |||
277 | self.cipher = Cipher( | ||
278 | Blowfish(key.encode("ascii")), ECB(), backend=default_backend()) | ||
279 | |||
280 | def _make_bytearray(self, data): | ||
281 | return bytearray(len(data) + (self.block_size - 1)) | ||
271 | 282 | ||
272 | def decrypt(self, data, strip_padding=True): | 283 | def decrypt(self, data, strip_padding=True): |
273 | buf = self._make_bytearray(data) | 284 | buf = self._make_bytearray(data) |
@@ -284,6 +295,24 @@ class BlowfishCryptor(object): | |||
284 | return bytes(buf[:len_enc]) + enc.finalize() | 295 | return bytes(buf[:len_enc]) + enc.finalize() |
285 | 296 | ||
286 | 297 | ||
298 | class PurePythonBlowfish(BlowfishCryptor): | ||
299 | """Pure Python 3 Blowfish Cryptor | ||
300 | |||
301 | Uses the pure python blowfish library but is only compatible with Python 3. | ||
302 | """ | ||
303 | |||
304 | def __init__(self, key): | ||
305 | import blowfish | ||
306 | self.cipher = blowfish.Cipher(key.encode("ascii")) | ||
307 | |||
308 | def decrypt(self, data, strip_padding=True): | ||
309 | data = b"".join(self.cipher.decrypt_ecb(data)) | ||
310 | return self._strip_padding(data) if strip_padding else data | ||
311 | |||
312 | def encrypt(self, data): | ||
313 | return b"".join(self.cipher.encrypt_ecb(self._add_padding(data))) | ||
314 | |||
315 | |||
287 | class Encryptor(object): | 316 | class Encryptor(object): |
288 | """Pandora Blowfish Encryptor | 317 | """Pandora Blowfish Encryptor |
289 | 318 | ||
@@ -292,8 +321,8 @@ class Encryptor(object): | |||
292 | """ | 321 | """ |
293 | 322 | ||
294 | def __init__(self, in_key, out_key): | 323 | def __init__(self, in_key, out_key): |
295 | self.bf_out = BlowfishCryptor(out_key) | 324 | self.bf_out = CryptographyBlowfish(out_key) |
296 | self.bf_in = BlowfishCryptor(in_key) | 325 | self.bf_in = CryptographyBlowfish(in_key) |
297 | 326 | ||
298 | @staticmethod | 327 | @staticmethod |
299 | def _decode_hex(data): | 328 | def _decode_hex(data): |