Ejemplo n.º 1
0
def decrypt_binary(ct_b64, key_hex):
    """Decrypt a ciphertext generated by encrypt_binary.

    ct_b64 (str): the ciphertext as produced by encrypt_binary.
    key_hex (str): the 16-bytes key in hex format used to encrypt.

    return (bytes): the plaintext.

    raise (ValueError): if the ciphertext is invalid.

    """
    key = hex_to_bin(key_hex)
    try:
        # Convert the ciphertext from a URL-safe base64 encoding to a
        # bytestring, which contains both the IV (the first 16 bytes) as well
        # as the encrypted padded plaintext.
        iv_ct = b64_to_bin(
            ct_b64.replace('-', '+').replace('_', '/').replace('.', '='))
        aes = AES.new(key, AES.MODE_CBC, iv_ct[:16])
        # Get the padded plaintext.
        pt_pad = aes.decrypt(iv_ct[16:])
        # Remove the padding.
        # TODO check that the padding is correct, i.e. that it contains at most
        # 15 bytes 0x00 preceded by a byte 0x01.
        pt = pt_pad.rstrip(b'\x00')[:-1]
        return pt
    except (TypeError, binascii.Error):
        raise ValueError('Could not decode from base64.')
    except ValueError:
        raise ValueError('Wrong AES cryptogram length.')
Ejemplo n.º 2
0
def decrypt_string(ct_b64, key=None):
    """Decrypt a ciphertext (ct_b64) encrypted with encrypt_string and
    return the corresponding plaintext.

    If key is not specified, it is obtained from the configuration.

    """
    if key is None:
        key = _get_secret_key_unhex()
    try:
        # Convert the ciphertext from a URL-safe base64 encoding to a
        # bytestring, which contains both the IV (the first 16 bytes) as well
        # as the encrypted padded plaintext.
        iv_ct = b64_to_bin(
            ct_b64.replace('-', '+').replace('_', '/').replace('.', '='))
        aes = AES.new(key, AES.MODE_CBC, iv_ct[:16])
        # Get the padded plaintext.
        pt_pad = aes.decrypt(iv_ct[16:])
        # Remove the padding.
        # TODO check that the padding is correct, i.e. that it contains at most
        # 15 bytes 0x00 preceded by a byte 0x01.
        pt = pt_pad.rstrip(b'\x00')[:-1]
        return pt
    except TypeError:
        raise ValueError('Could not decode from base64.')
    except ValueError:
        raise ValueError('Wrong AES cryptogram length.')
Ejemplo n.º 3
0
Archivo: crypto.py Proyecto: Nyrio/cms
def decrypt_binary(ct_b64, key_hex):
    """Decrypt a ciphertext generated by encrypt_binary.

    ct_b64 (str): the ciphertext as produced by encrypt_binary.
    key_hex (str): the 16-bytes key in hex format used to encrypt.

    return (bytes): the plaintext.

    raise (ValueError): if the ciphertext is invalid.

    """
    key = hex_to_bin(key_hex)
    try:
        # Convert the ciphertext from a URL-safe base64 encoding to a
        # bytestring, which contains both the IV (the first 16 bytes) as well
        # as the encrypted padded plaintext.
        iv_ct = b64_to_bin(
            ct_b64.replace('-', '+').replace('_', '/').replace('.', '='))
        aes = AES.new(key, AES.MODE_CBC, iv_ct[:16])
        # Get the padded plaintext.
        pt_pad = aes.decrypt(iv_ct[16:])
        # Remove the padding.
        # TODO check that the padding is correct, i.e. that it contains at most
        # 15 bytes 0x00 preceded by a byte 0x01.
        pt = pt_pad.rstrip(b'\x00')[:-1]
        return pt
    except (TypeError, binascii.Error):
        raise ValueError('Could not decode from base64.')
    except ValueError:
        raise ValueError('Wrong AES cryptogram length.')
Ejemplo n.º 4
0
 def test_invalid_alphabet(self):
     # binascii ignores invalid characters
     self.assertEqual(b64_to_bin("M\x00g.C,g\x0a"), b"\x32\x00\xa0")
Ejemplo n.º 5
0
 def test_invalid_length(self):
     with self.assertRaises(binascii.Error):
         b64_to_bin("MgC")
Ejemplo n.º 6
0
 def test_success(self):
     self.assertEqual(b64_to_bin("MgCg"), b"\x32\x00\xa0")
     self.assertEqual(b64_to_bin("/////w=="), b"\xFF\xFF\xFF\xFF")
     self.assertEqual(b64_to_bin("A" * (3000 * 4 // 3)), b"\x00" * 3000)