Exemple #1
0
    def test_finalize_with_tag_already_finalized(self, backend):
        key = binascii.unhexlify(b"e98b72a9881a84ca6b76e0f43e68647a")
        iv = binascii.unhexlify(b"8b23299fde174053f3d652ba")
        encryptor = ciphers.Cipher(AES(key), modes.GCM(iv),
                                   backend).encryptor()
        ciphertext = encryptor.update(b"abc") + encryptor.finalize()

        decryptor = ciphers.Cipher(AES(key), modes.GCM(iv, tag=encryptor.tag),
                                   backend).decryptor()
        decryptor.update(ciphertext)
        decryptor.finalize()
        with pytest.raises(AlreadyFinalized):
            decryptor.finalize_with_tag(encryptor.tag)
Exemple #2
0
def crypt_create(key_bytes,
                 is_encrypt_flag=None,
                 iv_bytes=None,
                 algorithm=ciphers_algorithms.AES,
                 mode=ciphers_modes.CTR):
    '''
    Create and return a crypto context for symmetric key encryption using the
    key key_bytes.
    
    Uses algorithm in mode with an IV of iv_bytes.
    If iv_bytes is None, an all-zero IV is used.

    AES CTR mode uses the same operations for encryption and decyption.
    '''
    #print "Key: " + binascii.hexlify(bytes(key_bytes))
    algo = algorithm(bytes(key_bytes))
    # The block_size is in bits
    if iv_bytes is None:
        iv_bytes = get_zero_pad(algo.block_size/BITS_IN_BYTE)
    cipher = ciphers.Cipher(algo, mode(bytes(iv_bytes)),
                            backend=backends.default_backend()) 
    if is_encrypt_flag:
        return cipher.encryptor()
    else:
        return cipher.decryptor()
    def _decrypt_block(self, block, mac_needs_iv=False):
        """Decrypt a block of data, with its MAC at the end."""
        # the last ten bytes of the block is the message authentication code
        payload, their_mac = block[:-10], block[-10:]

        # update the iv with the counter
        self._iv_drip[:4] = ByteHelper.write_bytes_int(self._iv_counter)
        self._iv_counter += 1

        # compute mac from the block body and compare
        mac = hmac.HMAC(self._mac_key, hashes.SHA256())
        if mac_needs_iv:
            mac.update(self._iv_drip)
        mac.update(payload)
        our_mac = mac.finalize()[:10]
        if their_mac != our_mac:
            self.logger.debug('MAC fail, their_mac %s our_mac %s', their_mac,
                              our_mac)
            raise Exception('Message Authentication Code fail')

        # decrypt contents
        decryptor = ciphers.Cipher(ciphers.algorithms.AES(self._cipher_key),
                                   ciphers.modes.CTR(
                                       self._iv_drip)).decryptor()
        return decryptor.update(payload) + decryptor.finalize()
def decrypt_unpad_check(input, string):
    """Combine the prior routines to convert the string into a key,
      extract out the IV, decrypt the remainder, unpad whatever decrypted,
      and check the SHA2 224 tag appended to the end.

   PARAMETERS
   ==========
   input: A bytes object to be decrypted according to the above.
   string: A string to be used as a key.

   RETURNS
   =======
   If the input could be decoded and the tag matches, the return value is a 
     bytes object containing the plaintext. In all other cases, the return is 
     None.
   """
    key = derive_key(string)
    iv = input[:16]
    ctext = input[16:]
    aes_cipher = ciphers.Cipher(ciphers.algorithms.AES(key),
                                ciphers.modes.CBC(iv))
    aes_decryptor = aes_cipher.decryptor()
    plain = aes_decryptor.update(ctext) + aes_decryptor.finalize()

    try:
        unpadder = padding.PKCS7(128).unpadder()
        data = unpadder.update(plain)
        data += unpadder.finalize()
    except:
        return None

    res = check_tag(data)
    return res
def _build_vectors():
    count = 0
    output = []
    key = None
    plaintext = binascii.unhexlify(32 * '0')
    for size in _SIZES_TO_GENERATE:
        for keyinfo in _RFC6229_KEY_MATERIALS:
            key = _key_for_size(size, keyinfo)
            cipher = ciphers.Cipher(algorithms.ARC4(binascii.unhexlify(key)),
                                    None, default_backend())
            encryptor = cipher.encryptor()
            current_offset = 0
            for offset in _RFC6229_OFFSETS:
                if offset % 16 != 0:
                    raise ValueError(
                        "Offset {} is not evenly divisible by 16".format(
                            offset))
                while current_offset < offset:
                    encryptor.update(plaintext)
                    current_offset += len(plaintext)
                output.append("\nCOUNT = {}".format(count))
                count += 1
                output.append("KEY = {}".format(key))
                output.append("OFFSET = {}".format(offset))
                output.append("PLAINTEXT = {}".format(
                    binascii.hexlify(plaintext)))
                output.append("CIPHERTEXT = {}".format(
                    binascii.hexlify(encryptor.update(plaintext))))
                current_offset += len(plaintext)
            assert not encryptor.finalize()
    return "\n".join(output)
 def _encrypt(self, data, iv=None):
     if iv is None:
         iv = os.urandom(_iv_len)
     cipher = cryptography.Cipher(self.cipher,
                                  mode=_mode[self.mode](iv),
                                  backend=self.backend).encryptor()
     return b''.join([iv, cipher.update(data)])
Exemple #7
0
    def encrypt(self, password, data):
        """Encrypt given data using md5 + salt + aes-128-cbc."""
        # IrssiNotifier requires null at the end
        databytes = data.encode() + bytes(1)
        padder = padding.PKCS7(128).padder()
        padded_data = padder.update(databytes) + padder.finalize()
        salt = os.urandom(8)
        key = None
        iv = None

        for n in range(2):
            # this following logic is similar to EVP_BytesToKey() from openssl
            md5hash = hashes.Hash(hashes.MD5())
            if key is not None:
                md5hash.update(key)
            md5hash.update(password.encode())
            md5hash.update(salt)
            md5 = md5hash.finalize()
            if key is None:
                key = md5
                continue
            if iv is None:
                iv = md5

        aes256cbc = ciphers.Cipher(ciphers.algorithms.AES(key),
                                   ciphers.modes.CBC(iv))
        encryptor = aes256cbc.encryptor()
        edata = encryptor.update(padded_data) + encryptor.finalize()
        edata = 'Salted__'.encode() + salt + edata
        edata = base64.b64encode(edata, b'-_')
        edata = edata.replace(b'=', b'')
        return edata
def aes_ecb(text, key, encrypt=False):
    """Decrypts the ciphertext in the file with known key."""
    cipher = ciphers.Cipher(algorithms.AES(key), modes.ECB(),
                            backends.default_backend())
    cryptor = cipher.encryptor() if encrypt else cipher.decryptor()
    crypt = cryptor.update(text) + cryptor.finalize()
    return crypt
Exemple #9
0
def decrypt(value: bytes) -> bytes:
    """Decrypt a string.

    :return: A decrypted string."""
    try:
        decrypted = base64.b64decode(value)
    except binascii.Error:
        raise CryptoError("Invalid encrypted token: invalid base64")

    if len(decrypted) < IV_BYTES_NEEDED + TAG_SIZE_BYTES:
        raise CryptoError("Invalid encrypted token: size check failure")

    iv = decrypted[:IV_BYTES_NEEDED]
    tag = decrypted[IV_BYTES_NEEDED:IV_BYTES_NEEDED + TAG_SIZE_BYTES]
    decrypted = decrypted[IV_BYTES_NEEDED + TAG_SIZE_BYTES:]
    cipher = ciphers.Cipher(
        ciphers.algorithms.AES(SECRET_KEY),
        ciphers.modes.GCM(iv, tag),
        backend=default_backend(),
    )
    decryptor = cipher.decryptor()
    try:
        return decryptor.update(
            decrypted) + decryptor.finalize()  # type: ignore[no-any-return]
    except cryptography.exceptions.InvalidTag:
        raise CryptoError("Invalid encrypted token: decryptor() failure")
Exemple #10
0
    def _decrypt_message(self, message):
        try:
            encrypted_message = base64.b64decode(message['body'])
        except (ValueError, TypeError):
            return
        iv = encrypted_message[:16]
        cipher = ciphers.Cipher(algorithms.AES(self._encryption_key),
                                modes.CBC(iv),
                                backend=crypto_backends.default_backend())
        try:
            decryptor = cipher.decryptor()
            data = (decryptor.update(encrypted_message[16:]) +
                    decryptor.finalize())
        except Exception:
            raise DecryptError(_('Encrypted data appears to be corrupted.'))

        # Strip the last n padding bytes where n is the last value in
        # the plaintext
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
        data = unpadder.update(data) + unpadder.finalize()
        try:
            message['body'] = pickle.loads(data)
        except pickle.UnpicklingError:
            # If the data is a string which didn't be serialized, there will
            # raise an exception. We just try to return the string itself.
            message['body'] = str(data, encoding="utf-8")
Exemple #11
0
    def build_cipher(self, alg='aes_128_cbc'):
        """
        :param alg: cipher algorithm
        :return: A Cipher instance
        """
        self.__class__._deprecation_notice()
        typ, bits, cmode = alg.lower().split('_')
        bits = int(bits)
        iv = _os.urandom(self.AES_BLOCK_SIZE)

        if len(iv) != self.AES_BLOCK_SIZE:
            raise Exception('Wrong iv size: {}'.format(len(iv)))

        if bits not in _ciphers.algorithms.AES.key_sizes:
            raise Exception('Unsupported key length: {}'.format(bits))

        if len(self.key) != bits / 8:
            raise Exception('Wrong Key length: {}'.format(len(self.key)))

        try:
            mode = self.POSTFIX_MODE[cmode]
        except KeyError:
            raise Exception('Unsupported chaining mode: {}'.format(cmode))

        cipher = _ciphers.Cipher(_ciphers.algorithms.AES(self.key),
                                 mode(iv),
                                 backend=_backends.default_backend())

        return cipher, iv
Exemple #12
0
    def __init__(self,
                 algorithm=None,
                 cipher_mode=None,
                 initialization_vector=None,
                 **kwargs):
        """Initializes a decrypter.

    Args:
      algorithm (Optional[Cryptography.CipherAlgorithm]): cipher algorithm.
      cipher_mode (Optional[str]): cipher mode.
      initialization_vector (Optional[bytes]): initialization vector.
      kwargs (dict): keyword arguments depending on the decrypter.

    Raises:
      ValueError: if the initialization_vector is required and not set.
    """
        if (cipher_mode != definitions.ENCRYPTION_MODE_ECB
                and not initialization_vector):
            raise ValueError('Missing initialization vector.')

        if cipher_mode == definitions.ENCRYPTION_MODE_CBC:
            mode = modes.CBC(initialization_vector)
        elif cipher_mode == definitions.ENCRYPTION_MODE_CFB:
            mode = modes.CFB(initialization_vector)
        elif cipher_mode == definitions.ENCRYPTION_MODE_ECB:
            mode = modes.ECB()
        elif cipher_mode == definitions.ENCRYPTION_MODE_OFB:
            mode = modes.OFB(initialization_vector)

        backend = backends.default_backend()
        cipher = ciphers.Cipher(algorithm, mode=mode, backend=backend)

        super(CryptographyBlockCipherDecrypter, self).__init__()
        self._algorithm = algorithm
        self._cipher_context = cipher.decryptor()
Exemple #13
0
def encryptKeyAES(options, manifestInput, encryptionInfo, payload):
    # Store the PSK ID
    pskId = manifestGet(manifestInput, 'resource.resource.manifest.payload.encryptionInfo.id.key', 'encryptionKeyId')
    if not pskId:
        LOG.critical('The aes-psk encryption mode requires a "encryptionKeyId" entry in the input JSON file')
        sys.exit(1)
    encryptionInfo["id"] = { "key" : codecs.decode(pskId, 'hex')}
    secret = options.payload_secret

    # Read the secret
    secret_data = utils.read_file(secret) if os.path.isfile(secret) else base64.b64decode(secret)
    if not secret_data:
        LOG.critical('The aes-psk encryption mode requires either a base64-encoded secret or a valid file to be passed via the "-s" option.')
        sys.exit(1)

    # generate an IV
    IV = os.urandom(nonceSize)
    # generate a new key
    key = os.urandom(nonceSize)

    cipherpayload = encryptClearText(payload, key, IV)

    # NOTE: In general, ECB is a poor choice, since it fails quickly to known-plaintext attacks. In this case, however,
    # ECB should be appropriate, since the plaintext is precisely one AES block, and it is comprised of high entropy
    # random data; therefore, the plaintext is never known.

    # Create the cipher object
    cipher = cryptoCiphers.Cipher(cryptoCiphers.algorithms.AES(bytes(secret_data)),
                                  cryptoCiphers.modes.ECB(), backend=backend) # nosec ignore bandit B404
    keyEncryptor = cipher.encryptor()
    # Encrypt the plain text
    cipherKey = keyEncryptor.update(bytes(key)) + encryptor.finalize()
    return ciphertext

    return IV, cipherKey, cipherpayload
Exemple #14
0
    def test_DecryptionCorrectness(self):

        encryption_key = self.fernet._encryption_key
        signing_key = self.fernet._signing_key

        iv = os.urandom(16)
        ptx = "this is a super secret message"
        timestamp = struct.pack(">Q", int(time.time()))

        cipher = ciphers.Cipher(ciphers.algorithms.AES(encryption_key),
                                ciphers.modes.CTR(iv), self._backend)

        encryptor = cipher.encryptor()
        ctx = encryptor.update(ptx) + encryptor.finalize()

        auth = cmac.CMAC(ciphers.algorithms.AES(signing_key),
                         backend=default_backend())
        auth.update(b"\x91" + timestamp + iv + ctx)
        mac = auth.finalize()

        # Assemble a ciphertext using token created by `cryptography`. Ensure Fermet
        # 0x91 can decrypt the ciphertext correctly.
        mocked_result = base64.urlsafe_b64encode(b"\x91" + timestamp + iv +
                                                 ctx + mac)

        fernet_result = self.fernet.encrypt(ptx, iv)

        assert mocked_result == fernet_result
        assert self.fernet.decrypt(mocked_result) == ptx
Exemple #15
0
def AES_from_key(key, iv=None, iv_block=16, encoding=fc.DEFAULT_ENC):
    """
    Create an AES cipher from a key

    Args:
        key <bytes> - session key of size 8 or 16

    Kwargs:
        iv <bytes> - initialization vector
        iv_block <int> - size of the random initialization vector for CBC mode
        encoding <str> - string coding

    Return:
        cipher <cryptography..Cipher object> - AES cipher
    """
    if isinstance(key, str):
        key = key.encode(encoding)
    if len(key) == 8:
        key2 = key + key[::-1]
    elif len(key) == 16:
        key2 = key
    elif len(key) > 16:
        key2 = key[:16]
    else:
        fab_log('AES requires a cipher key of length of N16!', verbose_mode=5)
        return
    iv = iv if iv is not None else key2
    AES_cipher = ciphers.Cipher(algorithm=ciphers.algorithms.AES(key2),
                                mode=ciphers.modes.CBC(iv))
    return AES_cipher
 def _too_old(self, mode, backend):
     key = b"\x00" * 16
     c = ciphers.Cipher(AES(key), mode, backend)
     encryptor = c.encryptor()
     buf = bytearray(32)
     with pytest.raises(NotImplementedError):
         encryptor.update_into(b"\x00" * 16, buf)
Exemple #17
0
def _decrypt(value):
    try:
        decrypted = base64.b64decode(value)
    except binascii.Error:
        LOG.error("Invalid encrypted token: invalid base64")
        return

    if len(decrypted) < IV_BYTES_NEEDED + TAG_SIZE_BYTES:
        LOG.error("Invalid encrypted token: size check failure")
        return

    iv = decrypted[:IV_BYTES_NEEDED]
    tag = decrypted[IV_BYTES_NEEDED:IV_BYTES_NEEDED + TAG_SIZE_BYTES]
    decrypted = decrypted[IV_BYTES_NEEDED + TAG_SIZE_BYTES:]
    cipher = ciphers.Cipher(ciphers.algorithms.AES(SECRET_KEY),
                            ciphers.modes.GCM(iv, tag),
                            backend=default_backend())
    decryptor = cipher.decryptor()
    try:
        decrypted = decryptor.update(decrypted) + decryptor.finalize()
    except cryptography.exceptions.InvalidTag:
        LOG.error("Invalid encrypted token: decryptor() failure")
        return

    try:
        decrypted = decrypted.decode()
    except UnicodeDecodeError:
        LOG.error("Invalid encrypted token: decode() failure")
        return

    try:
        return json.loads(decrypted)
    except json.JSONDecodeError:
        LOG.error("Invalid encrypted token: json.load() failure")
        return
Exemple #18
0
 def test_update_into_buffer_too_small_gcm(self, backend):
     key = b"\x00" * 16
     c = ciphers.Cipher(AES(key), modes.GCM(b"\x00" * 12), backend)
     encryptor = c.encryptor()
     buf = bytearray(5)
     with pytest.raises(ValueError):
         encryptor.update_into(b"testing", buf)
Exemple #19
0
    def decrypt(self, data_enc, password, salt):
        """Decrypt data.

        :param data: `bytes` object with encrypted data.
        :param password: The password (will be fed to the KDF in use).
        :param salt: The salt (will be fed to the KDF in use).
        :return: `bytes` object with cleartext data.
        """
        kdf = self.get_kdf(salt, self.key_size)
        key = kdf.derive(password)

        iv_bytes = self.block_size // 8
        iv = data_enc[0:iv_bytes]
        data_enc = data_enc[iv_bytes:]

        unpadder = padding.PKCS7(self.block_size).unpadder()
        decryptor = (ciphers.Cipher(self.algorithm(key),
                                    modes.CBC(iv),
                                    backend=default_backend())).decryptor()

        try:
            data = decryptor.update(data_enc) + decryptor.finalize()
            return unpadder.update(data) + unpadder.finalize()
        except (ValueError, TypeError):
            # No padding oracle scenario in our usecase, but probably a good habit not to raise with root cause.
            raise_from(AgentCryptException("Decryption failed."),
                       AgentCryptException("*redacted*"))
 def _decrypt(self, data, iv=None):
     if iv is None:
         iv = data[:_iv_len]
         data = data[_iv_len:]
     cipher = cryptography.Cipher(self.cipher,
                                  mode=_mode[self.mode](iv),
                                  backend=self.backend).decryptor()
     return cipher.update(data)
Exemple #21
0
def _decrypt(iv: bytes, tag: bytes, value: bytes, secret: bytes) -> bytes:
    cipher = ciphers.Cipher(
        ciphers.algorithms.AES(secret),
        ciphers.modes.GCM(iv, tag),
        backend=default_backend(),
    )
    decryptor = cipher.decryptor()
    return decryptor.update(value) + decryptor.finalize()
Exemple #22
0
 def test_max_chunk_size_fits_in_int32(self, backend):
     # max chunk must fit in signed int32 or else a call large enough to
     # cause chunking will result in the very OverflowError we want to
     # avoid with chunking.
     key = b"\x00" * 16
     c = ciphers.Cipher(AES(key), modes.ECB(), backend)
     encryptor = c.encryptor()
     backend._ffi.new("int *", encryptor._ctx._MAX_CHUNK_SIZE)
Exemple #23
0
def aes_decryptor(key):
    '''Return AES cipher in CTR mode for *key*'''

    cipher = crypto_ciphers.Cipher(
        crypto_ciphers.algorithms.AES(key),
        crypto_ciphers.modes.CTR(nonce=bytes(16)),
        backend=crypto_backend)
    return cipher.decryptor()
Exemple #24
0
    def decipher(self, encrypted_data, symmetric_key):
        encrypted_data = base64.b64decode(encrypted_data)
        iv_size = 16
        mode = ciphers.modes.GCM(b'\0' * iv_size, encrypted_data[-iv_size:], iv_size)
        decipher = ciphers.Cipher(ciphers.algorithms.AES(symmetric_key), mode, backend=self.backend).decryptor()
        decrypted = decipher.update(encrypted_data[:-16]) + decipher.finalize()
        decrypted = Token(decrypted)

        return decrypted
Exemple #25
0
def encryptClearText(cleartext, key, iv):
    backend = cryptoBackends.default_backend()
    iv_counter = int.from_bytes(bytes(iv), byteorder='big')
    # Create the cipher object
    cipher = cryptoCiphers.Cipher(cryptoCiphers.algorithms.AES(key), cryptoCiphers.modes.CTR(iv), backend=backend)
    encryptor = cipher.encryptor()
    # Encrypt the plain text
    ciphertext = encryptor.update(bytes(cleartext)) + encryptor.finalize()
    return ciphertext
Exemple #26
0
def test_invalid_mode_algorithm():
    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
        ciphers.Cipher(
            ARC4(b"\x00" * 16),
            modes.GCM(b"\x00" * 12),
        )

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
        ciphers.Cipher(
            ARC4(b"\x00" * 16),
            modes.CBC(b"\x00" * 12),
        )

    with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
        ciphers.Cipher(
            ARC4(b"\x00" * 16),
            modes.CTR(b"\x00" * 12),
        )
Exemple #27
0
 def encrypt(self, msg):
     padder = padding.PKCS7(ciphers.algorithms.AES.block_size).padder()
     padded_msg = padder.update(msg) + padder.finalize()
     iv = os.urandom(self._block_size_bytes)
     encryptor = ciphers.Cipher(ciphers.algorithms.AES(self._key),
                                ciphers.modes.CBC(iv),
                                self._backend).encryptor()
     _ciphertext = iv + encryptor.update(padded_msg) + encryptor.finalize()
     return _ciphertext
def test_invalid_backend():
    pretend_backend = object()

    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
        ciphers.Cipher(
            AES(b"AAAAAAAAAAAAAAAA"),
            modes.ECB(),
            pretend_backend,  # type: ignore[arg-type]
        )
Exemple #29
0
 def test_update_into_gcm(self, backend):
     key = binascii.unhexlify(b"e98b72a9881a84ca6b76e0f43e68647a")
     iv = binascii.unhexlify(b"8b23299fde174053f3d652ba")
     ct = binascii.unhexlify(b"5a3c1cf1985dbb8bed818036fdd5ab42")
     pt = binascii.unhexlify(b"28286a321293253c3e0aa2704a278032")
     c = ciphers.Cipher(AES(key), modes.GCM(iv), backend)
     encryptor = c.encryptor()
     buf = bytearray(len(pt) + 15)
     res = encryptor.update_into(pt, buf)
     assert res == len(pt)
     assert bytes(buf)[:res] == ct
     encryptor.finalize()
     c = ciphers.Cipher(AES(key), modes.GCM(iv, encryptor.tag), backend)
     decryptor = c.decryptor()
     res = decryptor.update_into(ct, buf)
     decryptor.finalize()
     assert res == len(pt)
     assert bytes(buf)[:res] == pt
Exemple #30
0
 def test_update_into(self, params, backend):
     key = binascii.unhexlify(params["key"])
     pt = binascii.unhexlify(params["plaintext"])
     ct = binascii.unhexlify(params["ciphertext"])
     c = ciphers.Cipher(AES(key), modes.ECB(), backend)
     encryptor = c.encryptor()
     buf = bytearray(len(pt) + 15)
     res = encryptor.update_into(pt, buf)
     assert res == len(pt)
     assert bytes(buf)[:res] == ct