diff --git a/beaker/crypto/pycrypto.py b/beaker/crypto/pycrypto.py index 55b319cc..9606f4fc 100644 --- a/beaker/crypto/pycrypto.py +++ b/beaker/crypto/pycrypto.py @@ -1,9 +1,44 @@ -"""Encryption module that uses pycryptopp or pycrypto""" +"""Encryption module that uses cryptodomex, pycryptopp, or pycrypto, whichever is +available first. + +cryptodomex is preferred over Pycryptopp because (as of 2021-01-26) it +is more actively maintained. + +""" + +try: + import Cryptodome + have_cryptodome = True +except ImportError: + have_cryptodome = False + try: - # Pycryptopp is preferred over Crypto because Crypto has had - # various periods of not being maintained, and pycryptopp uses - # the Crypto++ library which is generally considered the 'gold standard' - # of crypto implementations + import pycryptopp + have_pycryptopp = True +except ImportError: + have_pycryptopp = False + +try: + import Crypto + have_pycrypto = True +except ImportError: + have_pycrypto = False + +if have_cryptodome: + from Cryptodome.Cipher import AES + from Cryptodome.Util import Counter + + def aesEncrypt(data, key): + cipher = AES.new(key, AES.MODE_CTR, + counter=Counter.new(128, initial_value=0)) + + return cipher.encrypt(data) + + def aesDecrypt(data, key): + cipher = AES.new(key, AES.MODE_CTR, + counter=Counter.new(128, initial_value=0)) + return cipher.decrypt(data) +elif have_pycryptopp: from pycryptopp.cipher import aes def aesEncrypt(data, key): @@ -12,8 +47,7 @@ def aesEncrypt(data, key): # magic. aesDecrypt = aesEncrypt - -except ImportError: +elif have_pycrypto: from Crypto.Cipher import AES from Crypto.Util import Counter @@ -27,6 +61,8 @@ def aesDecrypt(data, key): cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(128, initial_value=0)) return cipher.decrypt(data) +else: + raise Exception("Could not find a suitable module to implement beaker.crypto.pycrypto") has_aes = True diff --git a/setup.py b/setup.py index efe063c0..fd26db33 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ INSTALL_REQUIRES.append('funcsigs') -TESTS_REQUIRE = ['pytest', 'Mock', 'pycryptodome'] +TESTS_REQUIRE = ['pytest', 'Mock', 'pycryptodomex'] if py_version == (2, 6): TESTS_REQUIRE.append('WebTest<2.0.24') @@ -90,7 +90,7 @@ extras_require={ 'crypto': ['pycryptopp>=0.5.12'], 'pycrypto': ['pycrypto'], - 'pycryptodome': ['pycryptodome'], + 'pycryptodome': ['pycryptodomex'], 'cryptography': ['cryptography'], 'testsuite': [TESTS_REQUIRE] },