def runTest(self):
        ARC2.new(b'\x00' * 16, ARC2.MODE_ECB, effective_keylen=40)
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 4, ARC2.MODE_ECB)
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 129, ARC2.MODE_ECB)

        self.assertRaises(ValueError, ARC2.new, bchr(0) * 16, ARC2.MODE_ECB,
                          effective_keylen=39)
        self.assertRaises(ValueError, ARC2.new, bchr(0) * 16, ARC2.MODE_ECB,
                          effective_keylen=1025)
    def runTest(self):
        # Encrypt/Decrypt data and test output parameter

        cipher = ARC2.new(b'4'*16, ARC2.MODE_ECB)

        pt = b'5' * 16
        ct = cipher.encrypt(pt)

        output = bytearray(16)
        res = cipher.encrypt(pt, output=output)
        self.assertEqual(ct, output)
        self.assertEqual(res, None)
        
        res = cipher.decrypt(ct, output=output)
        self.assertEqual(pt, output)
        self.assertEqual(res, None)

        output = memoryview(bytearray(16))
        cipher.encrypt(pt, output=output)
        self.assertEqual(ct, output)
        
        cipher.decrypt(ct, output=output)
        self.assertEqual(pt, output)

        self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
        self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)

        shorter_output = bytearray(7)
        self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output)
        self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
Esempio n. 3
0
    def runTest(self):
        # Encrypt/Decrypt data and test output parameter

        cipher = ARC2.new(b'4'*16, ARC2.MODE_ECB)

        pt = b'5' * 16
        ct = cipher.encrypt(pt)

        output = bytearray(16)
        res = cipher.encrypt(pt, output=output)
        self.assertEqual(ct, output)
        self.assertEqual(res, None)
        
        res = cipher.decrypt(ct, output=output)
        self.assertEqual(pt, output)
        self.assertEqual(res, None)

        import sys
        if sys.version[:3] != '2.6':
            output = memoryview(bytearray(16))
            cipher.encrypt(pt, output=output)
            self.assertEqual(ct, output)
        
            cipher.decrypt(ct, output=output)
            self.assertEqual(pt, output)

        self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
        self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)

        shorter_output = bytearray(7)
        self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output)
        self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
Esempio n. 4
0
    def decrypt(self, file_path, password):
        private_key = self.get_private_key(password)
        if private_key is None:
            return {'status': False, 'msg': "Cannot get private key"}
        with open(file_path, 'rb') as fi:
            try:
                msg = json.loads(fi.read())
            except ValueError:
                return {'status': False, 'msg': "File structure is damaged"}
            for key, value in msg.iteritems():
                msg[key] = b64decode(value)
            secret_key = PKCS1_OAEP.new(private_key).decrypt(msg['secret_key'])
            try:
                # init cipher
                if msg['alg'] == ALG_OPTIONS[0]:
                    cipher = AES.new(secret_key, AES.MODE_EAX, msg['nonce'])
                elif msg['alg'] == ALG_OPTIONS[1]:
                    cipher = AES.new(secret_key, AES.MODE_OCB, msg['nonce'])
                elif msg['alg'] == ALG_OPTIONS[2]:
                    cipher = AES.new(secret_key, AES.MODE_CFB, msg['iv'])
                elif msg['alg'] == ALG_OPTIONS[3]:
                    cipher = AES.new(secret_key, AES.MODE_CTR, msg['nonce'])
                elif msg['alg'] == ALG_OPTIONS[4]:
                    cipher = DES.new(secret_key, DES.MODE_OFB, iv=msg['iv'])
                elif msg['alg'] == ALG_OPTIONS[5]:
                    cipher = ARC2.new(secret_key, ARC2.MODE_CFB)
                elif msg['alg'] == ALG_OPTIONS[6]:
                    cipher = ARC4.new(secret_key)
                elif msg['alg'] == ALG_OPTIONS[7]:
                    cipher = ChaCha20.new(key=secret_key, nonce=msg['nonce'])
                elif msg['alg'] == ALG_OPTIONS[8]:
                    cipher = Salsa20.new(key=secret_key, nonce=msg['nonce'])
                else:
                    return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"}

                # decrypt and verify
                if msg['alg'] in ALG_OPTIONS[1:3]:
                    decrypted_msg = cipher.decrypt_and_verify(msg['cipher_text'], msg['tag'])
                elif msg['alg'] in ALG_OPTIONS[3:]:
                    decrypted_msg = cipher.decrypt(msg['cipher_text'])
                    SHA256.new(decrypted_msg).hexdigest(), msg['tag']
                    if SHA256.new(decrypted_msg).hexdigest() != msg['tag']:
                        raise ValueError
                else:
                    return {'status': False, 'msg': "Cannot define the algorithm used to encrypt this file"}
            except ValueError, KeyError:
                return {'status': False, 'msg': "Decrypt failed, you are not the owner of this file"}
            dir_path, file_name = os.path.split(file_path)
            with open(dir_path + '/' + msg['file_name'], 'wb') as fo:
                fo.write(decrypted_msg)
            return {'status': True, 'msg': "Successfully decrypted file %s" % file_path}
def pycryptodomexExamples():
    from Cryptodome.Cipher import DES, DES3, ARC2, ARC4, Blowfish, AES
    from Cryptodome.Random import get_random_bytes

    key = b'-8B key-'
    DES.new(key,
            DES.MODE_OFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    # ^^^^^^^

    key = DES3.adjust_key_parity(get_random_bytes(24))
    cipher = DES3.new(
        key, DES3.MODE_CFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^

    key = b'Sixteen byte key'
    cipher = ARC2.new(
        key, ARC2.MODE_CFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^

    key = b'Very long and confidential key'
    cipher = ARC4.new(key)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^

    key = b'An arbitrarily long key'
    cipher = Blowfish.new(
        key,
        Blowfish.MODE_CBC)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^^^^^

    key = b'Sixteen byte key'
    cipher = AES.new(key, AES.MODE_CCM)  # Compliant

    cipher = UnknownFlyingValue.new(
        key, UnknownMode.CBC)  # Compliant, doesn't matter

    # Force the engine to generate an ambiguous symbol, for code coverage only.
    ambiguous = "" if 42 * 42 < 1700 else (lambda x: x * x)
    cipher = ambiguous.new(key, Unknown.Mode)
def pycroptodomeExamples():
    from Crypto.Cipher import DES, DES3, ARC2, ARC4, Blowfish, AES
    from Crypto.Random import get_random_bytes

    key = b'-8B key-'
    DES.new(key,
            DES.MODE_OFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    # ^^^^^^^

    key = DES3.adjust_key_parity(get_random_bytes(24))
    cipher = DES3.new(
        key, DES3.MODE_CFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^
    key = b'Sixteen byte key'
    cipher = ARC2.new(
        key, ARC2.MODE_CFB)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^
    key = b'Very long and confidential key'
    cipher = ARC4.new(key)  # Noncompliant {{Use a strong cipher algorithm.}}
    #        ^^^^^^^^
    key = b'An arbitrarily long key'
    cipher = Blowfish.new(
        key,
        Blowfish.MODE_CBC)  # Noncompliant {{Use a strong cipher algorithm.}}
Esempio n. 7
0
    def encrypt(self, file_path, alg):
        if alg not in ALG_OPTIONS:
            return False

        with open(file_path, 'rb') as fi, open(file_path + ENCRYPT_EXTEND, 'wb') as fo:
            public_key = self.get_public_key()
            cipher_rsa = PKCS1_OAEP.new(public_key)
            plain_text = fi.read()
            msg = {'alg': alg}
            if alg == ALG_OPTIONS[0]:
                secret_key = Random.get_random_bytes(16)
                cipher = AES.new(secret_key, AES.MODE_EAX)
                msg.update({'nonce': cipher.nonce})
            elif alg == ALG_OPTIONS[1]:
                secret_key = Random.get_random_bytes(16)
                cipher = AES.new(secret_key, AES.MODE_OCB)
                msg.update({'nonce': cipher.nonce})
            elif alg == ALG_OPTIONS[2]:
                secret_key = Random.get_random_bytes(16)
                iv = Random.new().read(AES.block_size)
                cipher = AES.new(secret_key, AES.MODE_CFB, iv)
                msg.update({'iv': iv})
            elif alg == ALG_OPTIONS[3]:
                secret_key = Random.get_random_bytes(16)
                cipher = AES.new(secret_key, AES.MODE_CTR)
                msg.update({'nonce': cipher.nonce})
            elif alg == ALG_OPTIONS[4]:
                secret_key = Random.get_random_bytes(8)
                cipher = DES.new(secret_key, DES.MODE_OFB)
                msg.update({'iv': cipher.iv})
            elif alg == ALG_OPTIONS[5]:
                secret_key = Random.get_random_bytes(16)
                cipher = ARC2.new(secret_key, ARC2.MODE_CFB)
                msg.update({'iv': cipher.iv})
            elif alg == ALG_OPTIONS[6]:
                secret_key = Random.get_random_bytes(40)
                cipher = ARC4.new(secret_key)
            elif alg == ALG_OPTIONS[7]:
                secret_key = Random.get_random_bytes(32)
                cipher = ChaCha20.new(key=secret_key)
                msg.update({'nonce': cipher.nonce})
            elif alg == ALG_OPTIONS[8]:
                secret_key = Random.get_random_bytes(32)
                cipher = Salsa20.new(key=secret_key)
                msg.update({'nonce': cipher.nonce})
            else:
                return False

            if alg in ALG_OPTIONS[1:3]:
                cipher_text, tag = cipher.encrypt_and_digest(plain_text)
            elif alg in ALG_OPTIONS[3:]:
                cipher_text = cipher.encrypt(plain_text)
                tag = SHA256.new(plain_text).hexdigest()
            else:
                return False
            dir_path, file_name = os.path.split(file_path)
            msg.update({'secret_key': cipher_rsa.encrypt(secret_key), 'cipher_text': cipher_text, 'tag': tag, 'file_name': file_name})
            for key, value in msg.iteritems():
                msg[key] = b64encode(value).encode('utf-8')
            fo.write(json.dumps(msg))
        return True
Esempio n. 8
0
from Cryptodome.Cipher import DES as pycryptodomex_des
from Cryptodome.Cipher import XOR as pycryptodomex_xor
from Crypto.Hash import SHA
from Crypto import Random
from Crypto.Util import Counter
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers import algorithms
from cryptography.hazmat.primitives.ciphers import modes
from cryptography.hazmat.backends import default_backend
from struct import pack

key = b'Sixteen byte key'
iv = Random.new().read(pycrypto_arc2.block_size)
cipher = pycrypto_arc2.new(key, pycrypto_arc2.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')
cipher = pycryptodomex_arc2.new(key, pycryptodomex_arc2.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')

key = b'Very long and confidential key'
nonce = Random.new().read(16)
tempkey = SHA.new(key+nonce).digest()
cipher = pycrypto_arc4.new(tempkey)
msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')
cipher = pycryptodomex_arc4.new(tempkey)
msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')

iv = Random.new().read(bs)
key = b'An arbitrarily long key'
plaintext = b'docendo discimus '
plen = bs - divmod(len(plaintext),bs)[1]
padding = [plen]*plen
class Crypter(object):
    """Implements modern authenticated encryption for strings

    The current version (1) uses HMAC-SHA256 and AES256-CBC using
    Encrypt-then-MAC. Should be secure >>>2030 according to NIST standards.
    http://www.keylength.com/ for a summary of algorithms and expected
    security. The message is padded with null characters. This means that
    strings with null characters should not use this method unless a
    different padding scheme is added

    AES in GCM mode is faster, but the pycrypto implementation is immature.
    This may be a better choice for future versions.

    There is currently legacy support for decryption under the old key
    using ARC2
    TODO(devinlundberg): remove legacy ARC2 decryption support
    """
    __metaclass__ = SingletonType
    # Remove legacy crypter in future.
    _legacy_crypter = ARC2.new(PinballConfig.SECRET_KEY, ARC2.MODE_ECB)
    _aes_block_size = 16
    _padding_char = '\x00'

    def _serialize(self, ciphertext, mac, **params):
        """Creates a serialized crypto object with current version and key"""
        encoded_params = {k: v.encode('base64') for k, v in params.items()}
        return json.dumps({
            'version': PinballConfig.CRYPTO_VERSION,
            'ciphertext': ciphertext.encode('base64'),
            'auth': mac.encode('base64'),
            'params': encoded_params
        }).encode('base64')

    def _deserialize(self, encoded_ciphertext):
        """Gets version, ciphertext, auth, and params from serialized object"""
        try:
            ciphertext_json = encoded_ciphertext.decode('base64')
        except binascii.Error:
            raise CryptoException('Invalid Base64')
        try:
            ciphertext_obj = json.loads(ciphertext_json)
        except ValueError:
            raise CryptoException('Invalid JSON format')
        if any(key not in ciphertext_obj
               for key in ('version', 'ciphertext', 'auth', 'params')):
            raise CryptoException('Invalid JSON parameters')
        version = ciphertext_obj['version']
        try:
            ciphertext = ciphertext_obj['ciphertext'].decode('base64')
            auth = ciphertext_obj['auth'].decode('base64')
            params = {k: v.decode('base64')
                      for k, v in ciphertext_obj['params'].items()}
        except binascii.Error:
            raise CryptoException('Invalid Base64')
        except AttributeError:
            raise CryptoException('Unsupported types')
        return version, ciphertext, auth, params

    def _cbc_hmac_sha256_decrypt(self, ciphertext, auth, iv):
        """Authenticated decrypt using AES-CBC and HMAC SHA256
        Encrypt-then-MAC"""
        hmac = HMAC.new(PinballConfig.HMAC_KEY, digestmod=SHA256)
        hmac.update(ciphertext)
        hmac.update(iv)
        if not compare_digest(hmac.hexdigest(), auth):
            raise CryptoException('Decryption Failed')
        aes = AES.new(PinballConfig.AES_CBC_KEY, AES.MODE_CBC, iv)
        return aes.decrypt(ciphertext).rstrip(self._padding_char)

    def encrypt(self, message):
        """Encrypts string of any length using the current crypto version

        Args:
            message: The string that needs to be encrypted.

        Returns:
            A serialized authenticated encrypted object
        """
        iv = ''.join(chr(random.randint(0, 255))
                     for _ in range(self._aes_block_size))
        aes = AES.new(PinballConfig.AES_CBC_KEY, AES.MODE_CBC, iv)
        hmac = HMAC.new(PinballConfig.HMAC_KEY, digestmod=SHA256)
        padded_length = (len(message) + self._aes_block_size -
                         len(message) % (self._aes_block_size))
        padded_message = message.ljust(padded_length, self._padding_char)
        ciphertext = aes.encrypt(padded_message)
        hmac.update(ciphertext)
        hmac.update(iv)
        return self._serialize(ciphertext, hmac.hexdigest(), iv=iv)

    def decrypt(self, encoded_ciphertext):
        """Deserializes and decrypts a string with the current or legacy
        algorithms

        Args:
            encoded_ciphertext: The string that needs to be decrypted.

        Returns:
            The decrypted message.

        Throws:
            CryptoException: on failed decryption.
        """
        try:
            version, ciphertext, auth, params = self._deserialize(encoded_ciphertext)
        except CryptoException:
            # This should raise an exception when support for ARC2 ends.
            return self._legacy_crypter.decrypt(encoded_ciphertext).rstrip('0')
        if version == 1:
            if 'iv' not in params:
                raise CryptoException('Missing IV')
            return self._cbc_hmac_sha256_decrypt(ciphertext, auth, params['iv'])
        else:
            raise CryptoException('Unsupported Crypto Version')
Esempio n. 10
0
from Cryptodome.Cipher import DES, DES3, ARC2, ARC4, Blowfish, AES
from Cryptodome.Random import get_random_bytes

key = b'-8B key-'
DES.new(
    key, DES.MODE_OFB
)  # Noncompliant: DES works with 56-bit keys allow attacks via exhaustive search

key = DES3.adjust_key_parity(get_random_bytes(24))
cipher = DES3.new(
    key, DES3.MODE_CFB
)  # Noncompliant: Triple DES is vulnerable to meet-in-the-middle attack

key = b'Sixteen byte key'
cipher = ARC2.new(
    key,
    ARC2.MODE_CFB)  # Noncompliant: RC2 is vulnerable to a related-key attack

key = b'Very long and confidential key'
cipher = ARC4.new(
    key
)  # Noncompliant: vulnerable to several attacks (see https://en.wikipedia.org/wiki/RC4#Security)

key = b'An arbitrarily long key'
cipher = Blowfish.new(
    key, Blowfish.MODE_CBC
)  # Noncompliant: Blowfish use a 64-bit block size makes it vulnerable to birthday attacks