aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2017-10-01 01:28:24 +0000
committerMike Crute <mike@crute.us>2017-10-01 01:28:24 +0000
commitdd19641addd9537a11552def63a4438fa9aac1c8 (patch)
tree10d8cb874b1061219865415d56e3aade7559d4f2
parent5ba28244b68fcb8b375a86046545b7bd352050e4 (diff)
downloadpydora-dd19641addd9537a11552def63a4438fa9aac1c8.tar.bz2
pydora-dd19641addd9537a11552def63a4438fa9aac1c8.tar.xz
pydora-dd19641addd9537a11552def63a4438fa9aac1c8.zip
Add pure-python blowfish backend
-rw-r--r--pandora/transport.py63
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
15import base64 15import base64
16import requests 16import requests
17from requests.adapters import HTTPAdapter 17from requests.adapters import HTTPAdapter
18from cryptography.hazmat.backends import default_backend
19from cryptography.hazmat.primitives.ciphers import Cipher
20from cryptography.hazmat.primitives.ciphers.modes import ECB
21from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish
22 18
23from .errors import PandoraException 19from .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): 264class 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
298class 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
287class Encryptor(object): 316class 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):