示例#1
0
 def __init__(self,
              path,
              mode,
              callback,
              event,
              encrypted_upload=False,
              key=None,
              iv=None,
              *args):
     file.__init__(self, path, mode)
     self.event = event
     self.encrypted_upload = encrypted_upload
     self.seek(0, os.SEEK_END)
     if self.encrypted_upload:
         if os.name == 'nt':
             self.backend = backend
         else:
             self.backend = default_backend()
         self.encryptor = Cipher(algorithms.AES(key),
                                 GCM(iv),
                                 backend=self.backend).encryptor()
         self._total = self.tell() + TAGSIZE
     else:
         self._total = self.tell()
     self.seek(0)
     self._callback = callback
     self._args = args
     self._seen = 0
示例#2
0
 def test_nonexistent_aead_cipher(self):
     from cryptography.hazmat.backends.commoncrypto.backend import Backend
     b = Backend()
     cipher = Cipher(
         DummyCipher(), GCM(b"fake_iv_here"), backend=b,
     )
     with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
         cipher.encryptor()
示例#3
0
 def aes_decrypt_fast(self, key, iv, payload):
     # Use AES128 GCM with the given key and iv to decrypt the payload.
     data = payload[:-16]
     tag = payload[-16:]
     decryptor = Cipher(algorithms.AES(key),
                        GCM(iv, tag=tag),
                        backend=self.backend).decryptor()
     return decryptor.update(data) + decryptor.finalize()
示例#4
0
def aes_decrypt(key, iv, payload):
    """ Use AES128 GCM with the given key and iv to decrypt the payload. """
    data = payload[:-16]
    tag = payload[-16:]
    backend = default_backend()
    decryptor = Cipher(algorithms.AES(key), GCM(iv, tag=tag),
                       backend=backend).decryptor()
    return decryptor.update(data) + decryptor.finalize()
示例#5
0
 def encrypt(self, cleartext: bytes):
     # No need for padding as we are using GCM
     # Get a new iv for GCM
     iv = urandom(int(AES.block_size // 8))
     cipher = Cipher(self._hazmat_key, GCM(iv), backend=openssl)
     encryptor = cipher.encryptor()
     enc = encryptor.update(cleartext) + encryptor.finalize()
     return iv + enc + encryptor.tag
def aes_encrypt(key, iv, plaintext):
    """ Use AES128 GCM with the given key and iv to encrypt the plaintext. """
    if os.name == 'nt':
        _backend = backend
    else:
        _backend = default_backend()
    encryptor = Cipher(algorithms.AES(key), GCM(iv),
                       backend=_backend).encryptor()
    return encryptor.update(plaintext) + encryptor.finalize(), encryptor.tag
示例#7
0
 def aes_decrypt(self, payload):
     # Use AES128 GCM with the given key and iv to decrypt the payload.
     payload = payload.getvalue()
     data = payload[:-16]
     tag = payload[-16:]
     decryptor = Cipher(algorithms.AES(self.file.key),
                        GCM(self.file.iv, tag=tag),
                        backend=default_backend()).decryptor()
     return decryptor.update(data) + decryptor.finalize()
示例#8
0
def _encrypt(data, key_size, iv_size):
    if isinstance(data, str):
        data = data.encode()
    key = os.urandom(key_size)
    iv = os.urandom(iv_size)
    encryptor = Cipher(algorithms.AES(key), GCM(iv),
                       backend=default_backend()).encryptor()

    payload = encryptor.update(data) + encryptor.finalize()
    return key, iv, encryptor.tag, payload
示例#9
0
 def test_nonexistent_aead_cipher(self):
     from cryptography.hazmat.backends.commoncrypto.backend import Backend
     b = Backend()
     cipher = Cipher(
         DummyCipher(),
         GCM(b"fake_iv_here"),
         backend=b,
     )
     with pytest.raises(UnsupportedAlgorithm):
         cipher.encryptor()
示例#10
0
 def _aes_decrypt_fast(self, key, iv, payload):
     # Use AES128 GCM with the given key and iv to decrypt the payload.
     if os.name == 'nt':
         be = backend
     else:
         be = default_backend()
     data = payload[:-16]
     tag = payload[-16:]
     decryptor = Cipher(algorithms.AES(key), GCM(iv, tag=tag),
                        backend=be).decryptor()
     return decryptor.update(data) + decryptor.finalize()
示例#11
0
    def encrypt_and_sign(self, header, data):
        encryptor = Cipher(self._cipher(self._key), GCM(self._iv),
                           default_backend()).encryptor()

        if header:
            encryptor.authenticate_additional_data(header)

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

        self._update_iv()

        return ciphertext, encryptor.tag
示例#12
0
    def encrypt_and_sign(self, header, data):
        """Encrypt and sign a block of data"""

        encryptor = Cipher(self._cipher(self._key), GCM(self._iv),
                           default_backend()).encryptor()

        if header:
            encryptor.authenticate_additional_data(header)

        data = encryptor.update(data) + encryptor.finalize()

        self._update_iv()

        return header + data, encryptor.tag
示例#13
0
    def encrypt(self, msg, aad, iv, key):
        """Key Encryption with AES GCM

        :param msg: text to be encrypt in bytes
        :param aad: additional authenticated data in bytes
        :param iv: initialization vector in bytes
        :param key: encrypted key in bytes
        :return: (ciphertext, iv, tag)
        """
        self.check_iv(iv)
        cipher = Cipher(AES(key), GCM(iv), backend=default_backend())
        enc = cipher.encryptor()
        enc.authenticate_additional_data(aad)
        ciphertext = enc.update(msg) + enc.finalize()
        return ciphertext, enc.tag
示例#14
0
    def verify_and_decrypt(self, header, data, tag):
        decryptor = Cipher(self._cipher(self._key), GCM(self._iv, tag),
                           default_backend()).decryptor()

        if header:
            decryptor.authenticate_additional_data(header)

        try:
            plaintext = decryptor.update(data) + decryptor.finalize()
        except InvalidTag:
            plaintext = None

        self._update_iv()

        return plaintext
示例#15
0
    def decrypt(self, ciphertext, aad, iv, tag, key):
        """Key Decryption with AES GCM

        :param ciphertext: ciphertext in bytes
        :param aad: additional authenticated data in bytes
        :param iv: initialization vector in bytes
        :param tag: authentication tag in bytes
        :param key: encrypted key in bytes
        :return: message
        """
        self.check_iv(iv)
        cipher = Cipher(AES(key), GCM(iv, tag), backend=default_backend())
        d = cipher.decryptor()
        d.authenticate_additional_data(aad)
        return d.update(ciphertext) + d.finalize()
示例#16
0
 def parse_frame(self, frame):  # type: (bytes) -> bytes
     """Parse one encrypted frame (without size header) and get cleartext data."""
     if len(frame) < IV_SIZE + 16:
         raise AuthenticationError("Frame too short")
     try:
         iv = frame[:IV_SIZE]
         gcm_tag = frame[-16:]
         cipher_text = frame[IV_SIZE:-16]
         cipher = Cipher(AES(self._key), GCM(iv), default_backend())
         decryptor = cipher.decryptor()
         clear_text = decryptor.update(
             cipher_text) + decryptor.finalize_with_tag(gcm_tag)
         return clear_text
     except InvalidTag:
         raise AuthenticationError("Invalid GCM authentication tag")
示例#17
0
    def verify_and_decrypt(self, header, data, mac):
        """Verify the signature of and decrypt a block of data"""

        decryptor = Cipher(self._cipher(self._key), GCM(self._iv, mac),
                           default_backend()).decryptor()

        decryptor.authenticate_additional_data(header)

        try:
            data = decryptor.update(data) + decryptor.finalize()
        except InvalidTag:
            data = None

        self._update_iv()

        return data
示例#18
0
    def emit_frame(self,
                   data,
                   with_size_header=False):  # type: (bytes, bool) -> bytes
        """Emit one encrypted frame from input data ready to be send to the client."""
        iv = os.urandom(IV_SIZE)
        cipher = Cipher(AES(self._key), GCM(iv), default_backend())
        encryptor = cipher.encryptor()
        frame_list = [
            iv,
            encryptor.update(data),
            encryptor.finalize(), encryptor.tag
        ]
        frame = b"".join(frame_list)

        if with_size_header:
            frame = b"".join([struct.pack("!I", len(frame)), frame])
        return frame
示例#19
0
    def wrap(self, cek, headers, key):
        self._check_key(key)

        #: https://tools.ietf.org/html/rfc7518#section-4.7.1.1
        #: The "iv" (initialization vector) Header Parameter value is the
        #: base64url-encoded representation of the 96-bit IV value
        iv_size = 96
        iv = os.urandom(iv_size // 8)

        cipher = Cipher(AES(key), GCM(iv), backend=default_backend())
        enc = cipher.encryptor()
        ek = enc.update(cek) + enc.finalize()

        h = {
            'iv': to_native(urlsafe_b64encode(iv)),
            'tag': to_native(urlsafe_b64encode(enc.tag))
        }
        return {'ek': ek, 'header': h}
示例#20
0
    def unwrap(self, ek, headers, key):
        self._check_key(key)

        iv = headers.get('iv')
        if not iv:
            raise ValueError('Missing "iv" in headers')

        tag = headers.get('tag')
        if not tag:
            raise ValueError('Missing "tag" in headers')

        iv = urlsafe_b64decode(to_bytes(iv))
        tag = urlsafe_b64decode(to_bytes(tag))

        cipher = Cipher(AES(key), GCM(iv, tag), backend=default_backend())
        d = cipher.decryptor()
        cek = d.update(ek) + d.finalize()
        return cek
示例#21
0
    def unwrap(self, enc_alg, ek, headers, key):
        op_key = key.get_op_key('unwrapKey')
        self._check_key(op_key)

        iv = headers.get('iv')
        if not iv:
            raise ValueError('Missing "iv" in headers')

        tag = headers.get('tag')
        if not tag:
            raise ValueError('Missing "tag" in headers')

        iv = urlsafe_b64decode(to_bytes(iv))
        tag = urlsafe_b64decode(to_bytes(tag))

        cipher = Cipher(AES(op_key), GCM(iv, tag), backend=default_backend())
        d = cipher.decryptor()
        cek = d.update(ek) + d.finalize()
        if len(cek) * 8 != enc_alg.CEK_SIZE:
            raise ValueError('Invalid "cek" length')
        return cek
def aes_decrypt(_key, iv, payload):
    """ Use AES128 GCM with the given key and iv to decrypt the payload. """
    if len(_key) >= 32:
        # XEP-0384
        log.debug('XEP Compliant Key/Tag')
        data = payload
        key = _key[:16]
        tag = _key[16:]
    else:
        # Legacy
        log.debug('Legacy Key/Tag')
        data = payload[:-16]
        key = _key
        tag = payload[-16:]
    if os.name == 'nt':
        _backend = backend
    else:
        _backend = default_backend()
    decryptor = Cipher(algorithms.AES(key), GCM(iv, tag=tag),
                       backend=_backend).decryptor()
    return decryptor.update(data) + decryptor.finalize()
示例#23
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
示例#24
0
    def wrap(self, enc_alg, headers, key, preset=None):
        if preset and 'cek' in preset:
            cek = preset['cek']
        else:
            cek = enc_alg.generate_cek()

        op_key = key.get_op_key('wrapKey')
        self._check_key(op_key)

        #: https://tools.ietf.org/html/rfc7518#section-4.7.1.1
        #: The "iv" (initialization vector) Header Parameter value is the
        #: base64url-encoded representation of the 96-bit IV value
        iv_size = 96
        iv = os.urandom(iv_size // 8)

        cipher = Cipher(AES(op_key), GCM(iv), backend=default_backend())
        enc = cipher.encryptor()
        ek = enc.update(cek) + enc.finalize()

        h = {
            'iv': to_native(urlsafe_b64encode(iv)),
            'tag': to_native(urlsafe_b64encode(enc.tag))
        }
        return {'ek': ek, 'cek': cek, 'header': h}
示例#25
0
    def _decrypt(cls, fobj: io.BufferedIOBase,
                 input_size: typing.Optional[int],
                 privkey: x25519.X25519PrivateKey,
                 chunk_size: int) -> typing.Iterable[bytes]:
        if input_size is None:
            input_size = cls._get_size_till_eof(fobj)

        epubkey = x25519.X25519PublicKey.from_public_bytes(
            cls._read_exact(fobj, cls._PUBKEY_SIZE_BYTES))
        input_size -= cls._PUBKEY_SIZE_BYTES
        shared_secret = privkey.exchange(epubkey)
        iv = cls._read_exact(fobj, cls._IV_SIZE_BYTES)
        input_size -= cls._IV_SIZE_BYTES
        cipher_key = cls._derive_keys(shared_secret, iv)
        cipher_iv = iv[:cls._CIPHER_IV_SIZE_BYTES]
        decryptor = Cipher(algorithm=cls._CIPHER(cipher_key),
                           mode=GCM(cipher_iv),
                           backend=cls._CRYPTO_BACKEND).decryptor()

        if input_size < cls._AUTH_TAG_SIZE_BYTES:
            raise RuntimeError('input_size is too short')
        bufmv = memoryview(bytearray(chunk_size))
        auth_tag = b''
        while input_size > 0:
            bytes_read = fobj.readinto(bufmv)
            if bytes_read == 0:
                break
            input_size -= bytes_read
            if input_size <= cls._AUTH_TAG_SIZE_BYTES:
                auth_tag_part_len = cls._AUTH_TAG_SIZE_BYTES - input_size
                auth_tag += bufmv[bytes_read - auth_tag_part_len:bytes_read]
                auth_tag += fobj.read()
                yield decryptor.update(bufmv[:bytes_read - auth_tag_part_len])
            else:
                yield decryptor.update(bufmv[:bytes_read])
        yield decryptor.finalize_with_tag(auth_tag)
示例#26
0
    def decrypt_packet(data):
        data = bytearray(data)
        data_len = len(data)
        offset = 0

        if data[4] not in IQUIC.VERSIONS:
            return None

        salt = IQUIC.QUIC_VERSION_PARAMETERS[data[4]]['salt']

        offset = 5
        dcid_len = data[offset]
        dcid = data[offset + 1:offset + 1 + dcid_len]
        offset += 1 + dcid_len
        if offset >= data_len:
            return None

        scid_len = data[offset]
        scid = data[offset + 1:offset + 1 + scid_len]
        offset += 1 + scid_len
        if offset >= data_len:
            return None

        token_len = data[offset]
        token = data[offset + 1:offset + 1 + token_len]
        offset += 2 + token_len
        if offset >= data_len:
            return None

        initial_secret = IQUIC.hmac(salt, SHA256(), dcid)
        client_initial_secret = IQUIC.kdf_tls13(initial_secret, b'client in',
                                                32)
        key = IQUIC.kdf_tls13(client_initial_secret, b'quic key', 16)
        iv = IQUIC.kdf_tls13(client_initial_secret, b'quic iv', 12)
        hp = IQUIC.kdf_tls13(client_initial_secret, b'quic hp', 16)

        hp_encryptor = Cipher(algorithms.AES(hp),
                              mode=modes.ECB(),
                              backend=default_backend()).encryptor()
        buf = bytearray(31)
        sample = data[offset + 4:offset + 4 + IQUIC.SAMPLE_SIZE]
        hp_encryptor.update_into(sample, buf)
        mask = buf[:5]

        data[0] ^= mask[0] & 0x0F
        pn_length = (data[0] & 0x03) + 1
        if offset + pn_length >= data_len:
            return None
        for i in range(pn_length):
            data[offset + i] ^= mask[1 + i]
        pn = data[offset:offset + pn_length]
        plain_header = data[:offset + pn_length]

        nonce = bytearray(len(iv) - pn_length) + bytearray(pn)
        for i in range(len(iv)):
            nonce[i] ^= iv[i]

        cipher = Cipher(AES(key), GCM(iv), backend=default_backend())
        payload = cipher.decryptor().update(bytes(data[offset + pn_length:]))

        return payload[4:]
示例#27
0
 def decrypt(self, ciphertext: bytes):
     iv = ciphertext[:AES.block_size // 8]
     tag = ciphertext[-16:]
     cipher = Cipher(self._hazmat_key, GCM(iv, tag),
                     backend=openssl).decryptor()
     return cipher.update(ciphertext[16:-16]) + cipher.finalize()
示例#28
0
def _decrypt(key, iv, tag, data):
    decryptor = Cipher(algorithms.AES(key),
                       GCM(iv, tag=tag),
                       backend=default_backend()).decryptor()
    return decryptor.update(data) + decryptor.finalize()