Exemplo n.º 1
0
def test_aes_gcm(backend, wycheproof):
    key = binascii.unhexlify(wycheproof.testcase["key"])
    iv = binascii.unhexlify(wycheproof.testcase["iv"])
    aad = binascii.unhexlify(wycheproof.testcase["aad"])
    msg = binascii.unhexlify(wycheproof.testcase["msg"])
    ct = binascii.unhexlify(wycheproof.testcase["ct"])
    tag = binascii.unhexlify(wycheproof.testcase["tag"])
    if wycheproof.valid or wycheproof.acceptable:
        enc = Cipher(algorithms.AES(key), modes.GCM(iv), backend).encryptor()
        enc.authenticate_additional_data(aad)
        computed_ct = enc.update(msg) + enc.finalize()
        computed_tag = enc.tag
        assert computed_ct == ct
        assert computed_tag == tag
        dec = Cipher(
            algorithms.AES(key),
            modes.GCM(iv, tag, min_tag_length=len(tag)),
            backend
        ).decryptor()
        dec.authenticate_additional_data(aad)
        computed_msg = dec.update(ct) + dec.finalize()
        assert computed_msg == msg
    elif len(iv) == 0:
        with pytest.raises(ValueError):
            Cipher(algorithms.AES(key), modes.GCM(iv), backend)
    else:
        dec = Cipher(
            algorithms.AES(key),
            modes.GCM(iv, tag, min_tag_length=len(tag)),
            backend
        ).decryptor()
        dec.authenticate_additional_data(aad)
        dec.update(ct)
        with pytest.raises(InvalidTag):
            dec.finalize()
Exemplo n.º 2
0
    def decrypt(self):
        pad = self.enc_pad(self.enckey, self.pad_iv)

        aes = Cipher(AES(self.enckey), CTR(self.iv),
                     default_backend()).decryptor()
        self.fwd = pad + aes.update(self.onion[:self.fwd_end])
        self.msg = aes.update(self.onion[self.fwd_end:self.msg_end])
Exemplo n.º 3
0
class Rc4Xform(s_socket.SockXform):

    def __init__(self, rc4key):
        self.rc4key = rc4key

    def init(self, sock):

        txnonce = os.urandom(16)

        try:

            sock.setblocking(1)

            sock._raw_sendall(txnonce)

            rxnonce = sock._raw_recvall(16)
            if rxnonce == None:
                return

            txkey = hashlib.sha256( txnonce + self.rc4key ).digest()
            rxkey = hashlib.sha256( rxnonce + self.rc4key ).digest()

            self.txcrypt = Cipher( ARC4(txkey), mode=None, backend=default_backend() ).encryptor()
            self.rxcrypt = Cipher( ARC4(rxkey), mode=None, backend=default_backend() ).decryptor()

        finally:

            if sock.plex:
                sock.setblocking(0)

    def txform(self, byts):
        return self.txcrypt.update(byts)

    def rxform(self, byts):
        return self.rxcrypt.update(byts)
def main():
    if type(cipher_key) != str or len(cipher_key) != cipher_key_bytelen:
        return "no key", 500

    auth = request.args.get('auth', None)
    if auth is None:
        cleartext = '{"userid":%d,"is_admin":0}' % random.randint(1000000, 2000000)
        iv = os.urandom(cipher_block_bytelen)
        padder = padding.PKCS7(cipher.block_size).padder()
        padded_data = padder.update(cleartext) + padder.finalize()
        encryptor = Cipher(cipher(cipher_key), modes.CBC(iv), backend=backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()
        return redirect('/?auth=' + binascii.hexlify(iv + ciphertext))

    try:
        received = binascii.unhexlify(auth)
    except:
        return "hex error", 400
    # print "received"
    # hexdump.hexdump(received)
    # sys.stdout.flush()

    if len(received) < cipher_block_bytelen * 2:
        return "input too short", 400
    iv, ciphertext = received[:cipher_block_bytelen], received[cipher_block_bytelen:]

    decryptor = Cipher(cipher(cipher_key), modes.CBC(iv), backend=backend).decryptor()
    decrypted = decryptor.update(ciphertext) + decryptor.finalize()
    # print "decrypted"
    # hexdump.hexdump(decrypted)
    # sys.stdout.flush()

    unpadder = padding.PKCS7(cipher.block_size).unpadder()
    unpadded = unpadder.update(decrypted)
    try:
        unpadded += unpadder.finalize()
    except ValueError:
        return "padding error", 400
    # print "unpadded"
    # hexdump.hexdump(unpadded)
    # sys.stdout.flush()

    try:
        decoded = unpadded.decode('utf-8')
        parsed = json.loads(decoded)
    except:
        return "parsing error", 400

    if type(parsed) != dict or 'userid' not in parsed or 'is_admin' not in parsed:
        return "parsing error", 400

    if parsed['is_admin']:
        return "Hello user #%d, you are admin!" % parsed['userid']
    else:
        return "Hello user #%d!" % parsed['userid']
Exemplo n.º 5
0
class Rc4Skey(s_socket.SockXform):

    def __init__(self, rc4key):
        self.rc4key = rc4key
        self.txcrypt = Cipher( ARC4(rc4key), mode=None, backend=default_backend() ).encryptor()
        self.rxcrypt = Cipher( ARC4(rc4key), mode=None, backend=default_backend() ).decryptor()

    def init(self, sock):
        pass

    def txform(self, byts):
        return self.txcrypt.update(byts)

    def rxform(self, byts):
        return self.rxcrypt.update(byts)
Exemplo n.º 6
0
    def encrypt_with_hmac(self, data, data_id, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        if not isinstance(data_id, int):
            raise TypeError("data_id must be int.")

        main_parts = (
            struct.pack(config.FORMAT_CHAR, data_id) + data
        )

        # PKCS7 padding
        padded_data = self.add_padding(main_parts, algorithms.AES.block_size)
        # AES with CBC mode
        encryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), backend=self.backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + iv + ciphertext
        )

        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Exemplo n.º 7
0
def encrypt_v3(a_key, a_token, a_verbose = False):

    # Get sha-256 of key
    l_key = hashlib.sha256(a_key).hexdigest().decode('hex')

    # Generate iv
    l_iv = os.urandom(G_IV_SIZE_BYTES)  # TODO Make constant...

    # Construct an AES-GCM Cipher object with the given key and a
    # randomly generated IV.
    l_encryptor = Cipher(
        algorithms.AES(l_key),
        modes.GCM(l_iv),
        backend=default_backend()
    ).encryptor()

    # Encrypt the plaintext and get the associated ciphertext.
    # GCM does not require padding.
    l_ciphertext = l_encryptor.update(a_token) + l_encryptor.finalize()

    l_iv_ciphertext = l_iv + l_ciphertext + l_encryptor.tag

    #print 'TAG (len:%d) : %s'%(len(l_encryptor.tag), l_encryptor.tag)

    if a_verbose:
        print('+-------------------------------------------------------------')
        print('| l_iv:            %s'%(l_iv.encode('hex')))
        print('| l_ciphertext:    %s'%(l_ciphertext.encode('hex')))
        print('| l_tag:           %s'%(l_encryptor.tag.encode('hex')))
        print('+-------------------------------------------------------------')
        print('| l_encoded_token: %s'%(l_iv_ciphertext.encode('hex')))
        print('+-------------------------------------------------------------')

    return url_safe_base64_encode(l_iv_ciphertext)
Exemplo n.º 8
0
def decrypt_file(cipher_text):
    iv = cipher_text[:IV_LEN]
    decryptor = Cipher(
            algorithms.AES(key),
            modes.GCM(iv, cipher_text[IV_LEN:IV_LEN+TAG_LEN]),
            backend=b.default_backend()).decryptor()
    return decryptor.update(cipher_text[IV_LEN+TAG_LEN:]) + decryptor.finalize()
Exemplo n.º 9
0
def encrypt(encryption_key, iv, data):
    """Encrypt the payload."""
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    data = padder.update(data.encode()) + padder.finalize()

    encryptor = Cipher(algorithms.AES(encryption_key), modes.CBC(iv), default_backend()).encryptor()
    return base64.urlsafe_b64encode(encryptor.update(data) + encryptor.finalize())
Exemplo n.º 10
0
    def generate_secure_text(self, origin_text: str) -> str:
        """
        Encrypt and sign the origin text by ``cryptography`` library
        using AES GCM algorithm.

        :arg origin_text: is a string that will be encrypted by the provided
            security secret.
        """

        iv = os.urandom(16)

        content = struct.pack(
            "l", int(time.time())) + ensure_bytes(origin_text)

        encryptor = AESCipher(
            aes_algorithms.AES(ensure_bytes(self.__security_secret)),
            aes_modes.GCM(iv),
            backend=aes_backend()
        ).encryptor()

        ciphertext = encryptor.update(content) + encryptor.finalize()

        final_encrypted_text = iv
        final_encrypted_text += struct.pack("l", len(ciphertext))
        final_encrypted_text += ciphertext
        final_encrypted_text += encryptor.tag

        return ensure_str(base64.b64encode(final_encrypted_text))
Exemplo n.º 11
0
    def unwrap(self, key, ek):
        rk = self.get_key(key, 'decrypt')

        # Implement RFC 3394 Key Unwrap - 2.2.3
        # TODO: Use cryptography once issue #1733 is resolved
        iv = 'a6a6a6a6a6a6a6a6'
        Aiv = unhexlify(iv)

        R = [ek[i:i+8] for i in range(0, len(ek), 8)]
        A = R.pop(0)
        n = len(R)
        for j in range(5, -1, -1):
            for i in range(n - 1, -1, -1):
                AtR = _encode_int((_decode_int(A) ^ ((n*j)+i+1)), 64) + R[i]
                d = Cipher(algorithms.AES(rk), modes.ECB(),
                           backend=self.backend).decryptor()
                B = d.update(AtR) + d.finalize()
                A = B[:8]
                R[i] = B[-8:]

        if A != Aiv:
            raise InvalidJWEData('Decryption Failed')

        cek = b''.join(R)
        return cek
Exemplo n.º 12
0
    def _decrypt_data(self, data, timestamp, ttl):
        current_time = int(time.time())
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(data[:-32])
        try:
            h.verify(data[-32:])
        except InvalidSignature:
            raise InvalidToken

        iv = data[9:25]
        ciphertext = data[25:-32]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Exemplo n.º 13
0
def decrypt(value, key, stash=None):
    """
    Return a decrypted value
    """
    # extract fields using a regex
    res = re.match(r'^ENC\[AES256_GCM,data:(.+),iv:(.+),aad:(.+),tag:(.+)\]$',
                   value)
    # if the value isn't in encrypted form, return it as is
    if res is None:
        return value
    enc_value = b64decode(res.group(1))
    iv = b64decode(res.group(2))
    aad = b64decode(res.group(3))
    tag = b64decode(res.group(4))
    decryptor = Cipher(algorithms.AES(key),
                       modes.GCM(iv, tag),
                       default_backend()
                       ).decryptor()
    decryptor.authenticate_additional_data(aad)
    cleartext = decryptor.update(enc_value) + decryptor.finalize()
    if stash:
        # save the values for later if we need to reencrypt
        stash['iv'] = iv
        stash['aad'] = aad
        stash['cleartext'] = cleartext
    return cleartext
Exemplo n.º 14
0
def decrypt(data, key):
    iv = data[0:16]
    data = data[16:]
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()).decryptor()
    data = cipher.update(data) + cipher.finalize()
    padder = padding.PKCS7(128).unpadder()
    return padder.update(data) + padder.finalize()
Exemplo n.º 15
0
 def encrypt(self, orig_pkt, assoclen=None):
     """encrypt a MACsec frame for this Secure Association"""
     hdr = copy.deepcopy(orig_pkt)
     del hdr[MACsec].payload
     del hdr[MACsec].type
     pktlen = len(orig_pkt)
     if self.send_sci:
         hdrlen = NOSCI_LEN + SCI_LEN
     else:
         hdrlen = NOSCI_LEN
     if assoclen is None or not self.do_encrypt:
         if self.do_encrypt:
             assoclen = hdrlen
         else:
             assoclen = pktlen
     iv = self.make_iv(orig_pkt)
     assoc, pt, _ = MACsecSA.split_pkt(orig_pkt, assoclen)
     encryptor = Cipher(
         algorithms.AES(self.key),
         modes.GCM(iv),
         backend=default_backend()
     ).encryptor()
     encryptor.authenticate_additional_data(assoc)
     ct = encryptor.update(pt) + encryptor.finalize()
     hdr[MACsec].payload = Raw(assoc[hdrlen:assoclen] + ct + encryptor.tag)
     return hdr
Exemplo n.º 16
0
def aes_decrypt(passphrase, data):
    data = data.split('\n')
    if len(data) < 3:
        raise ValueError('Invalid encryption data')

    enc_salt = base64.b64decode(data[0])
    enc_iv = base64.b64decode(data[1])
    enc_data = base64.b64decode(data[2])

    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA1(),
        length=32,
        salt=enc_salt,
        iterations=1000,
        backend=default_backend(),
    )
    enc_key = kdf.derive(passphrase)

    cipher = Cipher(
        algorithms.AES(enc_key),
        modes.CBC(enc_iv),
        backend=default_backend()
    ).decryptor()
    data = cipher.update(enc_data) + cipher.finalize()

    return data.replace('\x00', '')
Exemplo n.º 17
0
def decrypt(key, associated_data, iv, ciphertext, tag):
    # Construct a Cipher object, with the key, iv, and additionally the
    # GCM tag used for authenticating the message.

    # OK.. all the objects passed in to this function are of type bytearray, but, it turns
    # out that the Cipher suite needs strings, despite saying in the documentation that it needs
    # bytes. Consequently all the parameter objects had to be converted to strings, hence the str()
    # around each one.
    # The moral of this story is strong typing is good.
    try:
        decryptor = Cipher(
            algorithms.AES(str(key)), modes.GCM(str(iv), str(tag)), backend=default_backend()
        ).decryptor()

        # We put associated_data back in or the tag will fail to verify
        # when we finalize the decryptor.
        decryptor.authenticate_additional_data(str(associated_data))

        # Decryption gets us the authenticated plaintext.
        # If the tag does not match an InvalidTag exception will be raised.
        ret = decryptor.update(str(ciphertext)) + decryptor.finalize()

    except Exception as e:
        print(" Failed to de-crypt Measurement with exception: {}: {}".format(e.__class__.__name__, e))
        ret = None

    return ret
Exemplo n.º 18
0
 def decrypt(self, orig_pkt, assoclen=None):
     """decrypt a MACsec frame for this Secure Association"""
     hdr = copy.deepcopy(orig_pkt)
     del hdr[MACsec].payload
     pktlen = len(orig_pkt)
     if self.send_sci:
         hdrlen = NOSCI_LEN + SCI_LEN
     else:
         hdrlen = NOSCI_LEN
     if assoclen is None or not self.do_encrypt:
         if self.do_encrypt:
             assoclen = hdrlen
         else:
             assoclen = pktlen - self.icvlen
     iv = self.make_iv(hdr)
     assoc, ct, icv = MACsecSA.split_pkt(orig_pkt, assoclen, self.icvlen)
     decryptor = Cipher(
         algorithms.AES(self.key),
         modes.GCM(iv, icv),
         backend=default_backend()
     ).decryptor()
     decryptor.authenticate_additional_data(assoc)
     pt = assoc[hdrlen:assoclen]
     pt += decryptor.update(ct)
     pt += decryptor.finalize()
     hdr[MACsec].type = struct.unpack('!H', pt[0:2])[0]
     hdr[MACsec].payload = Raw(pt[2:])
     return hdr
Exemplo n.º 19
0
def aes_encrypt(passphrase, data):
    enc_salt = os.urandom(32)
    enc_iv = os.urandom(16)

    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA1(),
        length=32,
        salt=enc_salt,
        iterations=1000,
        backend=default_backend(),
    )
    enc_key = kdf.derive(passphrase)

    data += '\x00' * (16 - (len(data) % 16))

    cipher = Cipher(
        algorithms.AES(enc_key),
        modes.CBC(enc_iv),
        backend=default_backend()
    ).encryptor()
    enc_data = cipher.update(data) + cipher.finalize()

    return '\n'.join([
        base64.b64encode(enc_salt),
        base64.b64encode(enc_iv),
        base64.b64encode(enc_data),
    ])
Exemplo n.º 20
0
    def lookup_origin_text(
        self, secure_text: str,
            valid_length: Optional[int]=None) -> str:
        try:
            encrypted_text_reader = io.BytesIO(base64.b64decode(secure_text))
        except:  # Unable to decode the data.
            return None

        try:
            iv = encrypted_text_reader.read(16)
            length = struct.unpack("l", encrypted_text_reader.read(8))[0]
            ciphertext = encrypted_text_reader.read(length)
            tag = encrypted_text_reader.read(16)
        except:  # Unable to split the data.
            return None

        decryptor = AESCipher(
            aes_algorithms.AES(self._security_secret),
            aes_modes.GCM(iv, tag),
            backend=aes_backend()
        ).decryptor()

        try:
            content = decryptor.update(ciphertext) + decryptor.finalize()
        except:  # Unable to decrypt and/or verify the data.
            return None

        timestamp = struct.unpack("l", content[:8])[0]
        text = content[8:]

        if valid_length and int(time.time()) - timestamp > valid_length:
            return None  # Data Expired.

        return ensure_str(text)
Exemplo n.º 21
0
    def decrypt(self, data, ttl=None):
        """
        :type data: bytes
        :type ttl: int
        :rtype: bytes
        """
        data = self._signer.unsign(data, ttl)

        iv = data[:16]
        ciphertext = data[16:]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv),
            self._backend).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken

        # Remove padding
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Exemplo n.º 22
0
    def unwrap(self, key, keylen, ek, headers):
        rk = self._get_key(key, 'decrypt')

        # Implement RFC 3394 Key Unwrap - 2.2.3
        # TODO: Use cryptography once issue #1733 is resolved
        iv = 'a6a6a6a6a6a6a6a6'
        aiv = unhexlify(iv)

        r = [ek[i:i + 8] for i in range(0, len(ek), 8)]
        a = r.pop(0)
        n = len(r)
        for j in range(5, -1, -1):
            for i in range(n - 1, -1, -1):
                da = _decode_int(a)
                atr = _encode_int((da ^ ((n * j) + i + 1)), 64) + r[i]
                d = Cipher(algorithms.AES(rk), modes.ECB(),
                           backend=self.backend).decryptor()
                b = d.update(atr) + d.finalize()
                a = b[:8]
                r[i] = b[-8:]

        if a != aiv:
            raise InvalidJWEData('Decryption Failed')

        cek = b''.join(r)
        if len(cek) != keylen:
            raise InvalidJWEKeyLength(keylen, len(cek))
        return cek
Exemplo n.º 23
0
def aes_key_wrap(wrapping_key, key_to_wrap, backend):
    if len(wrapping_key) not in [16, 24, 32]:
        raise ValueError("The wrapping key must be a valid AES key length")

    if len(key_to_wrap) < 16:
        raise ValueError("The key to wrap must be at least 16 bytes")

    if len(key_to_wrap) % 8 != 0:
        raise ValueError("The key to wrap must be a multiple of 8 bytes")

    # RFC 3394 Key Wrap - 2.2.1 (index method)
    encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor()
    a = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"
    r = [key_to_wrap[i:i + 8] for i in range(0, len(key_to_wrap), 8)]
    n = len(r)
    for j in range(6):
        for i in range(n):
            # every encryption operation is a discrete 16 byte chunk (because
            # AES has a 128-bit block size) and since we're using ECB it is
            # safe to reuse the encryptor for the entire operation
            b = encryptor.update(a + r[i])
            # pack/unpack are safe as these are always 64-bit chunks
            a = struct.pack(
                ">Q", struct.unpack(">Q", b[:8])[0] ^ ((n * j) + i + 1)
            )
            r[i] = b[-8:]

    assert encryptor.finalize() == b""

    return a + b"".join(r)
Exemplo n.º 24
0
def aes_key_unwrap(wrapping_key, wrapped_key, backend):
    if len(wrapped_key) < 24:
        raise ValueError("Must be at least 24 bytes")

    if len(wrapped_key) % 8 != 0:
        raise ValueError("The wrapped key must be a multiple of 8 bytes")

    if len(wrapping_key) not in [16, 24, 32]:
        raise ValueError("The wrapping key must be a valid AES key length")

    # Implement RFC 3394 Key Unwrap - 2.2.2 (index method)
    decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor()
    aiv = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"

    r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)]
    a = r.pop(0)
    n = len(r)
    for j in reversed(range(6)):
        for i in reversed(range(n)):
            # pack/unpack are safe as these are always 64-bit chunks
            atr = struct.pack(
                ">Q", struct.unpack(">Q", a)[0] ^ ((n * j) + i + 1)
            ) + r[i]
            # every decryption operation is a discrete 16 byte chunk so
            # it is safe to reuse the decryptor for the entire operation
            b = decryptor.update(atr)
            a = b[:8]
            r[i] = b[-8:]

    assert decryptor.finalize() == b""

    if not bytes_eq(a, aiv):
        raise InvalidUnwrap()

    return b"".join(r)
def verifyThenDecrypt(cipher, emailTime, key):
	encryptKey = key[16:]
	signKey = key[:16]
	payload = base64.urlsafe_b64decode(cipher)

	#verify timestamp to prevent replay
	try:
		timestamp, = struct.unpack(">Q", payload[1:9])
	except struct.error:
		raise ValueError('Invalid message')
	if timestamp + TTL < emailTime:
		raise Exception('Invalid timestamp: replay attack detected')

	#verify HMAC
	hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend())
	hasher.update(payload[:-32])
	try:
		hasher.verify(payload[-32:])
	except InvalidSignature:
		raise Exception('Invalid HMAC: data modification detected')

	#decrypt cipher text
	iv = payload[9:25]
	ciphertext = payload[25:-32]
	decryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv), default_backend()).decryptor()
	paddedPlaintext = decryptor.update(ciphertext)
	paddedPlaintext += decryptor.finalize()
	unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
	plaintext = unpadder.update(paddedPlaintext)
	plaintext += unpadder.finalize()

	return plaintext
Exemplo n.º 26
0
 def wrap_key(self, wrapping_key, key_to_wrap):
     # we don't use an RFC 3394 key wrap algorithm such as cryptography's
     # aes_wrap_key because it's slower and we have iv material readily
     # available so don't need a deterministic algorithm
     iv = self.create_iv()
     encryptor = Cipher(algorithms.AES(wrapping_key), modes.CTR(iv), backend=self.backend).encryptor()
     return {"key": encryptor.update(key_to_wrap), "iv": iv}
Exemplo n.º 27
0
    def encrypt(self, data):
        """
        .. warning::

            This should really have thread controls in it.
            If two threads are simutaneously encrypting,
            there is a small chance that the IVs would be the same.
            This would be **extremely** bad.

        :param data: The data to encrypt
        :type data: bytes
        :returns: IV + payload + TAG
        :rtype: bytes
        """
        # Grab && increment iv
        iv = self.iv
        self.iv = (int.from_bytes(iv, 'big') + 1).to_bytes(len(iv), 'big')

        # TODO: Do we have to make the encryptor every time?
        # Make the encryptor
        encryptor = Cipher(algorithms.AES(self.key),
                           modes.GCM(iv),
                           backend=default_backend()
                           ).encryptor()

        # Encrypt the data
        encryptor.authenticate_additional_data(iv)
        ciphertext = encryptor.update(data) + encryptor.finalize()

        return iv + ciphertext + encryptor.tag
Exemplo n.º 28
0
    def decrypt(self, data):
        """
        Decrypts an AESGCM payload.

        Relies on constants:
            :attr:`~crypto.aesgcm.IV_SIZE`

            :attr:`~crypto.aesgcm.TAG_SIZE`

        :param data: The raw data to decrypt
        :type data: bytes
        :returns: Decrypted data
        :rtype: bytes
        """
        iv = data[:IV_SIZE]
        payload = data[IV_SIZE: -TAG_SIZE]
        tag = data[-TAG_SIZE:]

        decryptor = Cipher(
            algorithms.AES(self.key),
            modes.GCM(iv, tag),
            backend=default_backend()
        ).decryptor()

        decryptor.authenticate_additional_data(iv)

        return decryptor.update(payload) + decryptor.finalize()
Exemplo n.º 29
0
def _decrypt_aesgcm(key, nonce, ciphertext_tag, associated_data):
    """
    Decrypts a ciphertext with associated data with AES GCM.

    Args:
        key:                encryption key
        nonce:              nonce for encryption
        ciphertext_tag:     ciphertext with appended tag to decrypt
        associated_data:    additional authenticated associated data (the AD in AEAD)

    Returns:
        decrypted plaintext
    """
    if len(ciphertext_tag) < MAC_BYTES:
        raise NoiseError('Truncated ciphertext (length < authentication tag length).')
    algo = algorithms.AES(key)
    assert len(nonce) == 12, 'Expected 96 bit nonce for AES-GCM'
    ciphertext, tag = ciphertext_tag[:-MAC_BYTES], ciphertext_tag[-MAC_BYTES:]
    mode = modes.GCM(nonce, tag)
    decryptor = Cipher(algo, mode, backend).decryptor()
    decryptor.authenticate_additional_data(associated_data)
    try:
        return decryptor.update(ciphertext) + decryptor.finalize()
    except InvalidTag as invalid_tag:
        raise NoiseError('GMAC failure') from invalid_tag
Exemplo n.º 30
0
 def decrypt(packed_encrypted_data, key, mac_key='', backend=BACKEND):
     """ Decrypts packed encrypted data as returned by encrypt with the same key. 
         If extra data is present, returns plaintext, extra_data. If not,
         returns plaintext. Raises InvalidTag on authentication failure. """
     header, ciphertext, iv, tag, extra_data = load_data(packed_encrypted_data)        
     algorithm, mode, authentication_algorithm = header.split('_', 2)   
     if algorithm.lower() in hashlib.algorithms_guaranteed:
         return cryptographyless.decrypt(packed_encrypted_data, key, mac_key, backend)
         
     mode_args = (iv, tag) if mode in AEAD_MODES else (iv, )
     decryptor = Cipher(getattr(algorithms, algorithm)(key), 
                        getattr(modes, mode)(*mode_args), 
                        backend=BACKEND).decryptor()
     if mode in AEAD_MODES:
         decryptor.authenticate_additional_data(extra_data)
     else:
         if not mac_key:
             raise ValueError("mac_key not supplied for {} mode".format(header))
         if not verify_mac(mac_key, save_data(tag, header + ciphertext + iv + extra_data), authentication_algorithm):
             raise InvalidTag("Failed to authenticate data")
         
     plaintext = decryptor.update(ciphertext) + decryptor.finalize()
     if extra_data:
         return (plaintext, extra_data)     
     else:
         return plaintext
Exemplo n.º 31
0
    def encrypt(self, message):
        iv = urandom(int(self.cipherAlg.block_size / 8))  #generate random iv

        padder = self.paddingAlg.padder()
        paddedMessage = padder.update(message) + padder.finalize()  #padding

        encryptor = Cipher(self.cipherAlg, self.mode(iv),
                           default_backend()).encryptor()
        ct = encryptor.update(
            paddedMessage) + encryptor.finalize()  #encryption

        ct, iv = b64encode(ct), b64encode(iv)

        h = HMAC(self.macKey, SHA256(), default_backend())
        h.update(ct + iv)
        mac = h.finalize()  #generate MAC

        return {
            "ct": ct.decode("ascii"),
            "iv_nonce": iv.decode("ascii"),
            "mac": b64encode(mac).decode("ascii")
        }
Exemplo n.º 32
0
def AES_sifrovani():
    global s_zprava, b_zprava, p, global_iv
    if p_symetricky_klic == "": AES_generovani_klicu("p")
    #Tohle nahradit šifrováním AES
    b_zprava = Encode(p_zprava)
    #f = Fernet(p_symetricky_klic)
    #s_zprava = f.encrypt(b_zprava)
    iv = os.urandom(12)

    sifrovani_AES = Cipher(algorithms.AES(p_symetricky_klic),
                           modes.GCM(iv),
                           backend=default_backend()).encryptor()

    #autorita - asi :/
    sifrovani_AES.authenticate_additional_data(
        b"authenticated but not encrweweweweypted payload")
    # kvůli gcmku malá zpráva
    s_zprava = sifrovani_AES.update(b_zprava) + sifrovani_AES.finalize()
    #print(s_zprava)

    p = sifrovani_AES.tag
    global_iv = iv
Exemplo n.º 33
0
    def decrypt(message: str, receiver_private_key: str) -> str:
        """
        decrypts message

        @param message: (str) message to decrypt
        @param receiver_private_key: (str) private key to decrypt with
        """
        message = Bytes.decode_bytes(message.encode('utf-8'))
        point = message[0:65]
        tag = message[65:81]
        ciphertext = message[81:]
        receiver_private_key_bytes = serialization.load_pem_private_key(
            receiver_private_key.encode('utf-8'),
            password=None,
            backend=default_backend()
        )
        sender_public_numbers = ec.EllipticCurvePublicNumbers.from_encoded_point(
            ec.SECP256K1(), point)
        sender_public_key = sender_public_numbers.public_key(default_backend())
        shared_key = receiver_private_key_bytes.exchange(
            ec.ECDH(),
            sender_public_key
        )
        iv = '000000000000'.encode('utf-8')
        xkdf = x963kdf.X963KDF(
            algorithm=hashes.SHA256(),
            length=32,
            sharedinfo=''.encode('utf-8'),
            backend=default_backend()
        )
        key = xkdf.derive(shared_key)
        decryptor = Cipher(
            algorithms.AES(key),
            modes.GCM(iv, tag),
            backend=default_backend()
        ).decryptor()

        dt = decryptor.update(ciphertext) + decryptor.finalize()
        return Crypt._unpad_data(dt).decode('utf-8')
Exemplo n.º 34
0
    def _encrypt(self, data: typing.Iterable[bytes]) -> typing.Iterable[bytes]:
        eprikey = x25519.X25519PrivateKey.generate()
        epubkey_bytes = eprikey.public_key().public_bytes(
            encoding=serialization.Encoding.Raw,
            format=serialization.PublicFormat.Raw)
        yield epubkey_bytes
        assert self._PUBKEY_SIZE_BYTES == len(epubkey_bytes)

        iv = os.urandom(self._IV_SIZE_BYTES)
        yield iv

        shared_secret = eprikey.exchange(self._enc_pubkey)
        cipher_key = self._derive_keys(shared_secret, iv)
        cipher_iv = iv[:self._CIPHER_IV_SIZE_BYTES]
        encryptor = Cipher(algorithm=self._CIPHER(cipher_key),
                           mode=GCM(cipher_iv),
                           backend=self._CRYPTO_BACKEND).encryptor()

        for chunk in data:
            yield encryptor.update(chunk)
        yield encryptor.finalize()
        yield encryptor.tag
Exemplo n.º 35
0
def encryptor(key,iv,plaintext):


    # Construct an AES-GCM Cipher object with the given key and a
    # randomly generated IV.
    encryptor = Cipher(
        algorithms.AES(key),
        modes.GCM(iv),
        backend=default_backend()
    ).encryptor()

    # associated_data will be authenticated but not encrypted,
    # it must also be passed in on decryption.


    # Encrypt the plaintext and get the associated ciphertext.
    # GCM does not require padding.
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()

    tag = encryptor.tag

    return ciphertext,tag
Exemplo n.º 36
0
def aes_encrypt(key, plaintext, associated_data):
    # Generate a random 96-bit IV.
    iv = os.urandom(12)

    # Construct an AES-GCM Cipher object with the given key and a
    # randomly generated IV.
    encryptor = Cipher(algorithms.AES(key),
                       modes.GCM(iv),
                       backend=default_backend()).encryptor()

    # associated_data will be authenticated but not encrypted,
    # it must also be passed in on decryption.
    encryptor.authenticate_additional_data(associated_data)

    # Encrypt the plaintext and get the associated ciphertext.
    # GCM does not require padding.
    ciphertext = encryptor.update(plaintext) + encryptor.finalize()

    #iv = iv.encode('utf-8')
    #ciphertext = ciphertext.encode('utf-8')
    tag = encryptor.tag
    return (iv, ciphertext, tag)
Exemplo n.º 37
0
    def encrypt(
            message: object,
            private_key: str,
            receiver_public_key: str) -> str:
        """
        encrypts message

        @param message: (object) message to encrypt
        @param private_key: (str) private key to encrypt message with
        @param receiver_public_key: (str) public key of person able to decrypt message
        """
        iv = '000000000000'.encode('utf-8')
        private_key_bytes = serialization.load_pem_private_key(
            private_key.encode('utf-8'),
            password=None,
            backend=default_backend()
        )
        receiver_public_key = serialization.load_pem_public_key(
            receiver_public_key.encode('utf-8'),
            backend=default_backend()
        )
        shared_key = private_key_bytes.exchange(ec.ECDH(), receiver_public_key)
        point = private_key_bytes.public_key().public_numbers().encode_point()
        xkdf = x963kdf.X963KDF(
            algorithm=hashes.SHA256(),
            length=32,
            sharedinfo=''.encode('utf-8'),
            backend=default_backend()
        )
        key = xkdf.derive(shared_key)
        encryptor = Cipher(
            algorithms.AES(key),
            modes.GCM(iv),
            backend=default_backend()
        ).encryptor()
        padded_message = Crypt._pad_data(json.dumps(message))
        ciphertext = encryptor.update(padded_message) + encryptor.finalize()
        complete_ciphertext = point + encryptor.tag + ciphertext
        return Bytes.encode_bytes(complete_ciphertext).decode('utf-8')
Exemplo n.º 38
0
    def wrap(self, key, bitsize, cek, headers):
        rk = self._get_key(key, 'encrypt')
        if not cek:
            cek = _randombits(bitsize)

        # Implement RFC 3394 Key Unwrap - 2.2.2
        # TODO: Use cryptography once issue #1733 is resolved
        iv = 'a6a6a6a6a6a6a6a6'
        a = unhexlify(iv)
        r = [cek[i:i + 8] for i in range(0, len(cek), 8)]
        n = len(r)
        for j in range(0, 6):
            for i in range(0, n):
                e = Cipher(algorithms.AES(rk), modes.ECB(),
                           backend=self.backend).encryptor()
                b = e.update(a + r[i]) + e.finalize()
                a = _encode_int(_decode_int(b[:8]) ^ ((n * j) + i + 1), 64)
                r[i] = b[-8:]
        ek = a
        for i in range(0, n):
            ek += r[i]
        return {'cek': cek, 'ek': ek}
Exemplo n.º 39
0
def decrypt(master_keys, ciphertext_blob, encryption_context):
    """Decrypt a ciphertext blob using a master key material.

    NOTE: This is not necessarily what KMS does, but it retains the same properties.

    NOTE: This function is NOT compatible with KMS APIs.

    :param dict master_keys: Mapping of a KmsBackend's known master keys
    :param bytes ciphertext_blob: moto-structured ciphertext blob encrypted under a moto master key in master_keys
    :param dict[str, str] encryption_context: KMS-style encryption context
    :returns: plaintext bytes and moto key ID
    :rtype: bytes and str
    """
    try:
        ciphertext = _deserialize_ciphertext_blob(
            ciphertext_blob=ciphertext_blob)
    except Exception:
        raise InvalidCiphertextException()

    aad = _serialize_encryption_context(encryption_context=encryption_context)

    try:
        key = master_keys[ciphertext.key_id]
    except KeyError:
        raise AccessDeniedException(
            "The ciphertext refers to a customer master key that does not exist, "
            "does not exist in this region, or you are not allowed to access.")

    try:
        decryptor = Cipher(algorithms.AES(key.key_material),
                           modes.GCM(ciphertext.iv, ciphertext.tag),
                           backend=default_backend()).decryptor()
        decryptor.authenticate_additional_data(aad)
        plaintext = decryptor.update(
            ciphertext.ciphertext) + decryptor.finalize()
    except Exception:
        raise InvalidCiphertextException()

    return plaintext, ciphertext.key_id
Exemplo n.º 40
0
    def decrypt(self):
        """Decrypt a blob using LPS. Implements FALLBACK and DP methods to derive
        or obtain the encryption key from the one stored in the PSE/credential file and then uses
        that encryption key to decrypt the credential using the AES cipher.

        LPS-protected PSEs/credentials are verified with both a CRC32 checksum and an HMAC.
        Validation of the checksum and HMAC is not implemented.

        :return: decrypted object
        :rtype: string

        :raise NotImplementedError: if the LPS method is not implemented
        :raise SAP_LPS_Decryption_Error: if there's an error decrypting the object
        """

        # Validate supported version
        if self.version != 2:
            log_lps.error("Version not supported")
            raise SAPLPSDecryptionError("Version not supported")

        # TODO: Calculate and validate CRC32

        # Decrypt the encryption key using the LPS method
        if self.lps_type in lps_encryption_key_decryptor:
            encryption_key = lps_encryption_key_decryptor[self.lps_type](self)
        else:
            log_lps.error("Invalid LPS decryption method")
            raise SAPLPSDecryptionError("Invalid LPS decryption method")

        # Decrypt the cipher text with the encryption key
        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(encryption_key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        plain = decryptor.update(self.encrypted_data) + decryptor.finalize()

        # TODO: Calculate and validate HMAC

        return plain
Exemplo n.º 41
0
def encrypt_key_attribute(ionic_sep, encrypted_attributes_name, attribute_values_to_encrypt):
    # To construct encrypted attributes:
    ## 1. Encode the original values as a JSON array in UTF-8.
    ## 2. Encrypt the encoded values using `SEP.CD:KS` key under 256-bit AES in GCM with the UTF-8 encoded attribute name used as
    ##    additional authenticated data. The initialization vector should be prepended to the cipher text and the auth tag should
    ##    be appended to the cipher text.
    ## 3. Encode the result using Base64.
    ## 4. Add the resulting string as the only value in the list under the attribute name.

    # 1. Encode the original values as a JSON array in UTF-8.
    json_array_of_attribute_values_to_encrypt = json.dumps(attribute_values_to_encrypt).encode(encoding='utf-8')

    # 2. Encrypt the encoded values using `SEP.CD:KS` key under 256-bit AES in GCM with the UTF-8 encoded attribute name used as
    #    additional authenticated data. The initialization vector should be prepended to the cipher text and the auth tag should
    #    be appended to the cipher text.
    # Create a 16-byte initialization vector of random bytes.
    attributes_to_encrypt_initialization_vector = os.urandom(16)

    # Create an AES-GCM cipher using the `SEP.CD:KS` as the key and the 16-byte initialization vector
    cipher = Cipher(algorithms.AES(ionic_sep.aesCdEiKey),
                    modes.GCM(attributes_to_encrypt_initialization_vector),
                    backend=default_backend()
    ).encryptor()

    # Set the authenticated data (AAD) to be the attributes name UTF-8 encoded
    cipher.authenticate_additional_data(encrypted_attributes_name.encode(encoding='utf-8'))

    # Encrypt the JSON array of attributes as UTF-8 bytes using 256-bit AES in GCM.
    attributes_to_encrypt_cipher_text = cipher.update(json_array_of_attribute_values_to_encrypt) + cipher.finalize()

    # Prepend the 16-byte initialization vector to the cipher text and append the auth tag to the cipher text.
    ## Prepend the resulting cipher text bytes with the initialization vector.
    ## Append the auth tag to the resulting cipher text.
    attributes_to_encrypt_iv_cipher_text_aad_bytes = b''.join([attributes_to_encrypt_initialization_vector,
                                                         attributes_to_encrypt_cipher_text,
                                                         cipher.tag])

    # 3. Encode the result using Base64
    return base64.b64encode(attributes_to_encrypt_iv_cipher_text_aad_bytes)
Exemplo n.º 42
0
    def __call__(self, fh):
        iv = self.randomness_source(self.algorithm.block_size / 8)
        salt = self.randomness_source(16)
        auth_salt = self.randomness_source(16)

        key = self.stretch_key(self.key, salt)
        auth_key = self.stretch_key(self.key, auth_salt)

        encryptor = Cipher(
            self.algorithm(key),
            self.cipher_mode(iv),
            backend=self.backend,
        ).encryptor()

        auth = self.auth(
            auth_key,
            self.auth_hash(),
            backend=self.backend,
        )

        header = self.encode_header(iv, salt, auth_salt)
        auth.update(header)
        yield header

        while True:
            chunk = fh.read(self.chunk_size)
            if not chunk:
                break

            out = encryptor.update(chunk)
            auth.update(out)
            yield out

        out = encryptor.finalize()
        auth.update(out)
        yield out

        signature = auth.finalize()
        yield signature
Exemplo n.º 43
0
    def _decrypt_cryptography(cls, b_salt, b_ciphertext, b_password, key_length):

        bs = algorithms.AES.block_size // 8
        b_key, b_iv = cls._aes_derive_key_and_iv(b_password, b_salt, key_length, bs)
        cipher = C_Cipher(algorithms.AES(b_key), modes.CBC(b_iv), CRYPTOGRAPHY_BACKEND).decryptor()
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        try:
            b_plaintext_envelope = unpadder.update(
                cipher.update(b_ciphertext) + cipher.finalize()
            ) + unpadder.finalize()
        except ValueError:
            # In VaultAES, ValueError: invalid padding bytes can mean bad
            # password was given
            raise AnsibleError("Decryption failed")

        b_plaintext, b_this_sha, b_test_sha = cls._parse_plaintext_envelope(b_plaintext_envelope)

        if b_this_sha != b_test_sha:
            raise AnsibleError("Decryption failed")

        return b_plaintext
Exemplo n.º 44
0
    def encryptedHandshakeMessage(self, rObj, hObj, kObj, serialize):
        serialize.extend(uint8(rObj.contentType))
        serialize.extend(uint16(rObj.version))
        rObj.epoch = 1
        serialize.extend(uint16(rObj.epoch))
        rObj.seqNumber = 0
        serialize.extend(uint48(rObj.seqNumber))

        handMessage = self.PRFforHandshake(hObj)

        self.getKeyFromMaster(hObj, kObj)

        iv = kObj.client_write_IV
        encryptor = Cipher(algorithms.AES(kObj.client_write_key),
                           modes.GCM(iv),
                           backend=default_backend()).encryptor()
        encryptor.authenticate_additional_data(kObj.client_write_MAC_key)
        ciphertext = encryptor.update(handMessage) + encryptor.finalize()

        rObj.length = len(ciphertext)
        serialize.extend(uint16(rObj.length))
        serialize.extend(ciphertext)
def encrypt_file(plainpath, cipherpath, password):    
    # Derive key with a random 16-byte salt
    salt = os.urandom(16)
    kdf = Scrypt(salt=salt, length=32,
                n=2**14, r=8, p=1,
                backend=default_backend())
    key = kdf.derive(password)

    # Generate a random 96-bit IV.
    iv = os.urandom(12)

    # Construct an AES-GCM Cipher object with the given key and IV.
    encryptor = Cipher(
        algorithms.AES(key),
        modes.GCM(iv),
        backend=default_backend()).encryptor()
    
    associated_data = iv + salt

    # associated_data will be authenticated but not encrypted,
    # it must also be passed in on decryption.
    encryptor.authenticate_additional_data(associated_data)
    
    with open(cipherpath, "wb+") as fcipher:
        # Make space for the header (12 + 16 + 16), overwritten last
        fcipher.write(b"\x00"*(12+16+16))
        
        # Encrypt and write the main body
        with open(plainpath, "rb") as fplain:
            for plaintext in iter(lambda: fplain.read(READ_SIZE), b''):
                ciphertext = encryptor.update(plaintext)
                fcipher.write(ciphertext)
            ciphertext = encryptor.finalize()   # Always b''.
            fcipher.write(ciphertext) # For clarity
            
        header = associated_data + encryptor.tag
        fcipher.seek(0,0)
        fcipher.write(header)
Exemplo n.º 46
0
    def decrypt(self, token):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes")

        if not token or six.indexbytes(token, 0) != 0x80:
            raise InvalidToken

        hmac = token[-32:]
        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(token[:-32])
        try:
            h.verify(hmac)
        except InvalidSignature:
            raise InvalidToken

        iv = token[1:17]
        ciphertext = token[17:-32]
        decryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv),
                           self.backend).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken

        plaintext = self.remove_padding(plaintext_padded,
                                        algorithms.AES.block_size)

        try:
            data_id, = struct.unpack(config.FORMAT_CHAR, plaintext[:8])
        except struct.error:
            raise InvalidToken

        if data_id == config.DUMMY_ID:
            raise DummyFileFound

        data = plaintext[8:]
        return data_id, data
Exemplo n.º 47
0
def encrypt(key=None, iv=None, plaintext=None, debug=0):
    """
    Encrypt the given plaintext using the AES-GCM with the given key and IV.
    :param key: encryption key
    :param iv: initialisation vector
    :param plaintext: data to encrypt
    :param debug: if 1, prints will be shown during execution; default 0, no prints are shown
    :return: the ciphertext
    """

    # Check if plaintext is set
    if plaintext is None:
        logging.error('sym_encrypt plaintext exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_encrypt plaintext')
        raise Exception

    # Check if key is set
    if key is None:
        logging.error('sym_encrypt key exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_encrypt key')
        raise Exception

    # Check if iv is set
    if iv is None:
        logging.error('sym_encrypt IV exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_encrypt IV')
        raise Exception

    # Construct an AES-GCM Cipher object with the given key and IV
    encryptor = Cipher(algorithms.AES(key),
                       modes.GCM(iv),
                       backend=default_backend()).encryptor()

    # Encrypt the plaintext and return the related ciphertext (GCM does not require padding)
    return encryptor.update(plaintext)
Exemplo n.º 48
0
class AES(object):
    algorithms = (
        0x0000660e,  # AES 128
        0x0000660f,  # AES 192
        0x00006610,  # AES 256
    )

    modes = {
        "cbc": lambda iv: modes.CBC(iv),
        "ecb": lambda iv: modes.ECB(),
        "ctr": lambda nonce: modes.CTR(nonce),
    }

    def __init__(self, key, iv=None, mode="cbc"):
        self.aes = Cipher(
            algorithms.AES(key), self.modes[mode](iv),
            backend=default_backend()
        ).decryptor()

    def decrypt(self, data):
        return self.aes.update(data) + self.aes.finalize()

    @staticmethod
    def import_key(data):
        if len(data) < BLOBHEADER.sizeof():
            return

        buf = io.BytesIO(data)
        header = BLOBHEADER.parse(buf.read(BLOBHEADER.sizeof()))
        if header.bType not in BlobTypes:
            return

        if header.aiKeyAlg not in AES.algorithms:
            return

        obj = BlobTypes[header.bType]()
        obj.parse(buf)
        return obj.export_key()
Exemplo n.º 49
0
def sym_decrypt(key=None, iv=None, ciphertext=None, debug=0):
    """
    Decrypt the ciphertext using AES-GCM with the given key and IV.
    :param key: decryption key
    :param iv: initialisation vector
    :param ciphertext: data to decrypt
    :param debug: if 1, prints will be shown during execution; default 0, no prints are shown
    :return: the plaintext
    """

    # Check if key is set
    if key is None:
        logging.error('sym_decrypt key exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_decrypt key')
        raise Exception

    # Check if iv is set
    if iv is None:
        logging.error('sym_decrypt IV exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_decrypt IV')
        raise Exception

    # Check if ciphertext is set
    if ciphertext is None:
        logging.error('sym_decrypt ciphertext exception')
        if debug:  # ONLY USE FOR DEBUG
            print('EXCEPTION in sym_decrypt ciphertext')
        raise Exception

    # Construct a Cipher object, with the key, IV and additionally the GCM tag used for authenticating the message
    decryptor = Cipher(algorithms.AES(key),
                       modes.GCM(iv),
                       backend=default_backend()).decryptor()

    # Decrypt the ciphertext
    return decryptor.update(ciphertext)
Exemplo n.º 50
0
class Decryptor(object):
    """Abstract decryption handler.

    :param algorithm: Algorithm used to encrypt this body
    :type algorithm: aws_encryption_sdk.identifiers.Algorithm
    :param bytes key: Raw source key
    :param bytes associated_data: Associated Data to send to decryption subsystem
    :param bytes iv: IV value with which to initialize decryption subsystem
    :param bytes tag: Tag with which to validate ciphertext
    """
    def __init__(self, algorithm, key, associated_data, iv, tag):
        self.source_key = key

        # Construct a decryptor object with the given key and a provided IV.
        # This is intentionally generic to leave an option for non-Cipher decryptor types in the future.
        self._decryptor = Cipher(algorithm.encryption_algorithm(key),
                                 algorithm.encryption_mode(iv, tag),
                                 backend=default_backend()).decryptor()

        # Put associated_data back in or the tag will fail to verify when the _decryptor is finalized.
        self._decryptor.authenticate_additional_data(associated_data)

    def update(self, ciphertext):
        """Updates _decryptor with provided ciphertext.

        :param bytes ciphertext: Ciphertext to decrypt
        :returns: Decrypted plaintext
        :rtype: bytes
        """
        return self._decryptor.update(ciphertext)

    def finalize(self):
        """Finalizes and closes _decryptor.

        :returns: Final decrypted plaintext
        :rtype: bytes
        """
        return self._decryptor.finalize()
Exemplo n.º 51
0
    def encrypt(self, value, associated_data: bytes = b'', stash=None):

        if not value and not isinstance(value, bool):
            return ""

        if stash and 'iv' in stash and 'cleartext' in stash and stash['cleartext'] == value:
            iv = stash['iv']
        else:
            iv = os.urandom(32)

        # Construct an AES-GCM Cipher object with the given key and a
        # randomly generated IV.
        encryptor = Cipher(
            algorithms.AES(self.key),
            modes.GCM(iv),
        ).encryptor()

        # associated_data will be authenticated but not encrypted,
        # it must also be passed in on decryption.
        encryptor.authenticate_additional_data(associated_data)

        # Encrypt the plaintext and get the associated ciphertext.
        # GCM does not require padding.
        ciphertext = encryptor.update(value.encode('utf-8')) + encryptor.finalize()

        if isinstance(value, str):
            valtype = 'str'
        elif isinstance(value, bool):
            valtype = 'bool'
        elif isinstance(value, int):
            valtype = 'int'
        elif isinstance(value, float):
            valtype = 'float'
        else:
            valtype = 'bytes'

        return f"ENC[AES256_GCM,data:{b64encode(ciphertext).decode('utf-8')},iv:{b64encode(iv).decode('utf-8')}," \
               f"tag:{b64encode(encryptor.tag).decode('utf-8')},type:{valtype}]"
Exemplo n.º 52
0
def aes_key_unwrap_with_padding(wrapping_key, wrapped_key, backend):
    if len(wrapped_key) < 16:
        raise InvalidUnwrap("Must be at least 16 bytes")

    if len(wrapping_key) not in [16, 24, 32]:
        raise ValueError("The wrapping key must be a valid AES key length")

    if len(wrapped_key) == 16:
        # RFC 5649 - 4.2 - exactly two 64-bit blocks
        decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor()
        b = decryptor.update(wrapped_key)
        assert decryptor.finalize() == b""
        a = b[:8]
        data = b[8:]
        n = 1
    else:
        r = [wrapped_key[i:i + 8] for i in range(0, len(wrapped_key), 8)]
        encrypted_aiv = r.pop(0)
        n = len(r)
        a, r = _unwrap_core(wrapping_key, encrypted_aiv, r, backend)
        data = b"".join(r)

    # 1) Check that MSB(32,A) = A65959A6.
    # 2) Check that 8*(n-1) < LSB(32,A) <= 8*n.  If so, let
    #    MLI = LSB(32,A).
    # 3) Let b = (8*n)-MLI, and then check that the rightmost b octets of
    #    the output table_s are zero.
    (mli, ) = struct.unpack(">I", a[4:])
    b = (8 * n) - mli
    if (not bytes_eq(a[:4], b"\xa6\x59\x59\xa6")
            or not 8 * (n - 1) < mli <= 8 * n
            or (b != 0 and not bytes_eq(data[-b:], b"\x00" * b))):
        raise InvalidUnwrap()

    if b == 0:
        return data
    else:
        return data[:-b]
Exemplo n.º 53
0
def myEncrypt(message, key):

    if (len(key) < constants.CONST_KEY_BYTES):
        print("Error: key length less than 32 bytes")
        return

    # Creates a random string of 16 bytes
    iv = os.urandom(constants.CONST_IV_BYTES)

    # Here we set the parameters for the encryptor
    # We use AES and CBC
    encryptor = Cipher(algorithms.AES(key),
                       modes.CBC(iv),
                       backend=default_backend()).encryptor()

    # Encode the message to base64
    encoded = base64.b64encode(message)
    encoded = addPadding(encoded)

    # We encrypt the message
    cipherText = encryptor.update(encoded) + encryptor.finalize()

    return (cipherText, iv)
def _wrap_core(
    wrapping_key: bytes,
    a: bytes,
    r: typing.List[bytes],
    backend: Backend,
) -> bytes:
    # RFC 3394 Key Wrap - 2.2.1 (index method)
    encryptor = Cipher(AES(wrapping_key), ECB(), backend).encryptor()
    n = len(r)
    for j in range(6):
        for i in range(n):
            # every encryption operation is a discrete 16 byte chunk (because
            # AES has a 128-bit block size) and since we're using ECB it is
            # safe to reuse the encryptor for the entire operation
            b = encryptor.update(a + r[i])
            # pack/unpack are safe as these are always 64-bit chunks
            a = struct.pack(">Q",
                            struct.unpack(">Q", b[:8])[0] ^ ((n * j) + i + 1))
            r[i] = b[-8:]

    assert encryptor.finalize() == b""

    return a + b"".join(r)
def encrypt(key, pt, aad):
    '''AES in GCM Mode encrytion function
        parameters:
            key: 128 bit random key
            pt: plaintext for encryption 
                type: bytes 
            aad: authenticated associated data
                type: bytes '''
    iv = os.urandom(12)  # 96 bit initialization vector

    encryptor = Cipher(
        algorithms.AES(key),  # using AES block cipher
        modes.GCM(iv),  # in GCM mode
        backend=default_backend()).encryptor(
        )  # creating a AESGCM cipher object

    encryptor.authenticate_additional_data(
        aad
    )  # authenticated associate data will be authenticated but not encrypted
    ct = encryptor.update(
        pt) + encryptor.finalize()  # getting cipher text after encryption

    return (iv, ct, encryptor.tag)
def _unwrap_core(
    wrapping_key: bytes,
    a: bytes,
    r: typing.List[bytes],
    backend: Backend,
) -> typing.Tuple[bytes, typing.List[bytes]]:
    # Implement RFC 3394 Key Unwrap - 2.2.2 (index method)
    decryptor = Cipher(AES(wrapping_key), ECB(), backend).decryptor()
    n = len(r)
    for j in reversed(range(6)):
        for i in reversed(range(n)):
            # pack/unpack are safe as these are always 64-bit chunks
            atr = (struct.pack(">Q",
                               struct.unpack(">Q", a)[0] ^ ((n * j) + i + 1)) +
                   r[i])
            # every decryption operation is a discrete 16 byte chunk so
            # it is safe to reuse the decryptor for the entire operation
            b = decryptor.update(atr)
            a = b[:8]
            r[i] = b[-8:]

    assert decryptor.finalize() == b""
    return a, r
Exemplo n.º 57
0
def decrypt_payload(ciphertext,
                    ciphertext_key,
                    iv,
                    tag,
                    encryption_context={}):
    """
    Decrypt CIS payload using KMS encrypted key.

    :ciphertext: encrypted payload
    :ciphertext_key: encrypted KMS derived key
    :iv: AES initialization vector used to encrypt payload
    :tag: AES GCM authentication code
    """

    plaintext_key = kms.decrypt(
        CiphertextBlob=ciphertext_key,
        EncryptionContext=encryption_context).get('Plaintext')

    decryptor = Cipher(algorithms.AES(plaintext_key),
                       modes.GCM(iv, tag),
                       backend=default_backend()).decryptor()

    return decryptor.update(ciphertext) + decryptor.finalize()
Exemplo n.º 58
0
def crypto(payload):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.ciphers import (Cipher, algorithms,
                                                        modes)
    from cryptography.hazmat.primitives import padding

    payload_type = payload[4]

    decryptor = Cipher(algorithms.AES(keys[payload[4]]),
                       modes.ECB(),
                       backend=default_backend()).decryptor()

    data = decryptor.update(payload[42:])

    unpadder = padding.PKCS7(128).unpadder()
    unpad = unpadder.update(data)
    unpad += unpadder.finalize()
    payload_data = load_packet(unpad)

    if payload_type == 0x70:
        if 'key' in payload_data:
            keys[0x64] = payload_data['key'].encode('ascii')
    return payload_data
Exemplo n.º 59
0
    def decrypt(self, fpath, outpath):
        """

        decrypt data file
        Args:
            fpath: raw file path
            outpath: encrpyted file path

        Returns:
            None

        """
        with open(fpath, 'rb') as infile, open(outpath, 'wb') as outfile:
            iv = infile.read(16)
            decryptor = Cipher(algorithms.AES(self.key), modes.CFB(iv),
                               self.backend).decryptor()

            for buffer in iter(functools.partial(infile.read, 4096), b''):
                data = decryptor.update(buffer)
                outfile.write(data)

            data = decryptor.finalize()
            outfile.write(data)
Exemplo n.º 60
0
class AES_CTR_cryptography(object):
    """AES in CTR mode"""

    block_size = 16

    def __init__(self, key, nonce, cnt=0):
        """initialize AES in ECB mode with the given key and nonce buffer
        
        key  : 16 bytes buffer
        nonce: 8 most significant bytes buffer of the counter initial value
               counter will be incremented starting at 0
        cnt  : uint64, 8 least significant bytes value of the counter
               default is 0
        """
        self.aes = Cipher(algorithms.AES(key),
                          modes.CTR(nonce + pack('>Q', cnt)),
                          backend=_backend).encryptor()

    def encrypt(self, data):
        """encrypt / decrypt data with the key and IV set at initialization"""
        return self.aes.update(data)

    decrypt = encrypt