Exemplo n.º 1
0
    def test_ciphers(self):
        backend = MultiBackend([
            DummyHashBackend([]),
            DummyCipherBackend([
                (algorithms.AES, modes.CBC),
            ])
        ])
        assert backend.cipher_supported(
            algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16)
        )

        cipher = Cipher(
            algorithms.AES(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        cipher.encryptor()
        cipher.decryptor()

        cipher = Cipher(
            algorithms.Camellia(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        with pytest.raises(UnsupportedCipher):
            cipher.encryptor()
        with pytest.raises(UnsupportedCipher):
            cipher.decryptor()
Exemplo n.º 2
0
    def test_ciphers(self):
        backend = MultiBackend([
            DummyHashBackend([]),
            DummyCipherBackend([
                (algorithms.AES, modes.CBC),
            ])
        ])
        assert backend.cipher_supported(
            algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16)
        )

        cipher = Cipher(
            algorithms.AES(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        cipher.encryptor()
        cipher.decryptor()

        cipher = Cipher(
            algorithms.Camellia(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.encryptor()
        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.decryptor()
Exemplo n.º 3
0
    def test_nonexistent_cipher(self, backend, mode):
        cipher = Cipher(
            DummyCipherAlgorithm(), mode, backend
        )
        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.encryptor()

        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.decryptor()
Exemplo n.º 4
0
    def test_nonexistent_cipher(self, backend):
        cipher = Cipher(
            DummyCipher(), object(), backend
        )
        with pytest.raises(UnsupportedAlgorithm):
            cipher.encryptor()

        with pytest.raises(UnsupportedAlgorithm):
            cipher.decryptor()
Exemplo n.º 5
0
    def test_nonexistent_cipher(self, backend, mode):
        cipher = Cipher(
            DummyCipher(), mode, backend
        )
        with pytest.raises(UnsupportedCipher):
            cipher.encryptor()

        with pytest.raises(UnsupportedCipher):
            cipher.decryptor()
Exemplo n.º 6
0
class BasicCipher:
    """Shim for basic ciphers"""

    def __init__(self, cipher_name, key, iv):
        cipher, mode, initial_bytes = _cipher_algs[cipher_name]

        self._cipher = Cipher(cipher(key), mode(iv) if mode else None,
                              default_backend())
        self._initial_bytes = initial_bytes
        self._encryptor = None
        self._decryptor = None

    def encrypt(self, data):
        """Encrypt a block of data"""

        if not self._encryptor:
            self._encryptor = self._cipher.encryptor()

            if self._initial_bytes:
                self._encryptor.update(self._initial_bytes * b'\0')

        return self._encryptor.update(data)

    def decrypt(self, data):
        """Decrypt a block of data"""

        if not self._decryptor:
            self._decryptor = self._cipher.decryptor()

            if self._initial_bytes:
                self._decryptor.update(self._initial_bytes * b'\0')

        return self._decryptor.update(data)
Exemplo n.º 7
0
def _aes_decrypt(key, iv, tag, data, aead=''):
    backend = default_backend()
    cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend=backend)
    decryptor = cipher.decryptor()
    if aead:
        decryptor.authenticate_additional_data(aead)
    return decryptor.update(data) + decryptor.finalize()
Exemplo n.º 8
0
    def decrypt(self, private_key_unserialized, ciphertext):
        self.debug("decrypting data...")

        private_key = self.serialize_key(private_key_unserialized, "private")

        # Decompose the signed ciphertext into its respective parts
        # signature = ciphertext_signed[:256]
        # ciphertext = ciphertext_signed[256:]
        symkey_encrypted = ciphertext[:256]
        data_encrypted = ciphertext[256:]

        # Validate the signature
        # self.signature_validate(signature, ciphertext, public_key)

        # Decrypt the symmetric key using the private key
        symkey_decrypted = private_key.decrypt(
            symkey_encrypted,
            padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None),
        )

        # Separate the encrypted symmetric key from the encrypted data
        symkey = symkey_decrypted[:16]
        iv = symkey_decrypted[16:]

        # Decrypt the data then remove padding
        cipher = Cipher(algorithms.AES(symkey), modes.CBC(iv), backend=default_backend())
        decryptor = cipher.decryptor()
        data_padded = decryptor.update(data_encrypted) + decryptor.finalize()
        data = self.depad(data_padded)

        self.debug("decryption complete.")

        return data
Exemplo n.º 9
0
def aead_exception_test(backend, cipher_factory, mode_factory):
    cipher = Cipher(
        cipher_factory(binascii.unhexlify(b"0" * 32)),
        mode_factory(binascii.unhexlify(b"0" * 24)),
        backend
    )
    encryptor = cipher.encryptor()
    encryptor.update(b"a" * 16)
    with pytest.raises(NotYetFinalized):
        encryptor.tag
    with pytest.raises(AlreadyUpdated):
        encryptor.authenticate_additional_data(b"b" * 16)
    encryptor.finalize()
    with pytest.raises(AlreadyFinalized):
        encryptor.authenticate_additional_data(b"b" * 16)
    with pytest.raises(AlreadyFinalized):
        encryptor.update(b"b" * 16)
    with pytest.raises(AlreadyFinalized):
        encryptor.finalize()
    cipher = Cipher(
        cipher_factory(binascii.unhexlify(b"0" * 32)),
        mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16),
        backend
    )
    decryptor = cipher.decryptor()
    decryptor.update(b"a" * 16)
    with pytest.raises(AttributeError):
        decryptor.tag
Exemplo n.º 10
0
 def test_creates_decryptor(self, backend):
     cipher = Cipher(
         algorithms.AES(binascii.unhexlify(b"0" * 32)),
         modes.CBC(binascii.unhexlify(b"0" * 32)),
         backend
     )
     assert isinstance(cipher.decryptor(), base.CipherContext)
Exemplo n.º 11
0
class CipherShim:
    def __init__(self, cipher, mode, block_size, key, iv, initial_bytes):
        if mode:
            mode = mode(iv)

        self._cipher = Cipher(cipher(key), mode, default_backend())
        self._initial_bytes = initial_bytes
        self._encryptor = None
        self._decryptor = None

        self.block_size = block_size

    def encrypt(self, data):
        if not self._encryptor:
            self._encryptor = self._cipher.encryptor()

            if self._initial_bytes:
                self._encryptor.update(self._initial_bytes * b'\0')

        return self._encryptor.update(data)

    def decrypt(self, data):
        if not self._decryptor:
            self._decryptor = self._cipher.decryptor()

            if self._initial_bytes:
                self._decryptor.update(self._initial_bytes * b'\0')

        return self._decryptor.update(data)
Exemplo n.º 12
0
    def decrypt(self, k, a, iv, e, t):
        """ Decrypt according to the selected encryption and hashing
        functions.
        :param k: Encryption key (optional)
        :param a: Additional Authenticated Data
        :param iv: Initialization Vector
        :param e: Ciphertext
        :param t: Authentication Tag

        Returns plaintext or raises an error
        """
        hkey = k[:self.keysize]
        dkey = k[self.keysize:]

        # verify mac
        if not constant_time.bytes_eq(t, self._mac(hkey, a, iv, e)):
            raise InvalidJWEData('Failed to verify MAC')

        # decrypt
        cipher = Cipher(algorithms.AES(dkey), modes.CBC(iv),
                        backend=self.backend)
        decryptor = cipher.decryptor()
        d = decryptor.update(e) + decryptor.finalize()
        unpadder = PKCS7(self.blocksize).unpadder()
        return unpadder.update(d) + unpadder.finalize()
Exemplo n.º 13
0
    def decrypt(self, data, associated_data=b""):
        decoded_data = base64.urlsafe_b64decode(data)
        mac = decoded_data[-16:]
        iv = decoded_data[0:16]
        cipher_text = decoded_data[16:-16]

        associated_data_length = struct.pack(">Q", len(associated_data) * 8)

        h = hmac.HMAC(self.mac_key, hashes.SHA256(), self.backend)
        h.update(associated_data)
        h.update(iv)
        h.update(cipher_text)
        h.update(associated_data_length)
        if not constant_time.bytes_eq(mac, h.finalize()[:16]):
            raise ValueError("data provided has an invalid signature.")

        cipher = Cipher(
            algorithms.AES(self.encryption_key), modes.CBC(iv), self.backend
        )

        decryptor = cipher.decryptor()
        plain_text = decryptor.update(cipher_text) + decryptor.finalize()

        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
        unpadded_data = unpadder.update(plain_text) + unpadder.finalize()

        return unpadded_data
Exemplo n.º 14
0
    def decrypt(keyBits, encryptedData, params):
        """
        Decrypt the encryptedData using the keyBits according the encrypt params.

        :param Blob keyBits: The key value.
        :param Blob encryptedData: The data to decrypt.
        :param EncryptParams params: This decrypts according to
          params.getAlgorithmType() and other params as needed such as
          params.getInitialVector().
        :return: The decrypted data.
        :rtype: Blob
        """
        if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.ECB(), backend = default_backend())
        elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc:
            cipher = Cipher(algorithms.AES(
              keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()),
              backend = default_backend())
        else:
            raise RuntimeError("unsupported encryption mode")

        # For the cryptography package, we have to remove the padding.
        decryptor = cipher.decryptor()
        resultWithPad = decryptor.update(encryptedData.toBytes()) + decryptor.finalize()
        if sys.version_info[0] <= 2:
            padLength = ord(resultWithPad[-1])
        else:
            padLength = resultWithPad[-1]

        return Blob(resultWithPad[:-padLength], False)
Exemplo n.º 15
0
    def _decrypt(self, b, strip_padding=True):
        """Decrypt a byte string.

        Uses the AES 256-bit symmetric key cypher.

        Args:
            b: the byte string to decrypt.
            strip_padding: whether to remove the padding (padding is required
                by AES2 to make the encrypted data an exact multiple of 16
                bytes in length).

        Returns:
            The decrypted data as a byte string.

        """
        from cryptography.hazmat.primitives.ciphers \
            import Cipher, algorithms, modes
        from cryptography.hazmat.backends import default_backend

        backend = default_backend()
        cypher = Cipher(
            algorithms.AES(self.__key), modes.CBC(self.__iv), backend=backend)
        decryptor = cypher.decryptor()
        result = decryptor.update(b) + decryptor.finalize()
        if strip_padding:
            result = result[:-result[-1]]
        return result
Exemplo n.º 16
0
def get_cipher(key, method, op, iv):
    if method == 'bypass':
        return bypass()
    if method in ('salsa20', 'chacha20', 'chacha20-ietf'):
        return Salsa20Crypto(method, key, iv, op)
    elif method == 'rc4-md5':
        md5 = hashlib.md5()
        md5.update(key)
        md5.update(iv)
        key = md5.digest()
        method = 'rc4'
    cipher = None

    if method.startswith('rc4'):
        pass
    elif method.endswith('ctr'):
        mode = modes.CTR(iv)
    elif method.endswith('ofb'):
        mode = modes.OFB(iv)
    elif method.endswith('cfb'):
        mode = modes.CFB(iv)
    else:
        raise ValueError('operation mode "%s" not supported!' % method.upper())

    if method.startswith('rc4'):
        cipher = Cipher(algorithms.ARC4(key), None, default_backend())
    elif method.startswith('aes'):
        cipher = Cipher(algorithms.AES(key), mode, default_backend())
    elif method.startswith('camellia'):
        cipher = Cipher(algorithms.Camellia(key), mode, default_backend())
    else:
        raise ValueError('crypto algorithm "%s" not supported!' % method.upper())

    return cipher.encryptor() if op else cipher.decryptor()
Exemplo n.º 17
0
def decrypt_blob(storage, blob_id, key, offset=0, length=None):
    """Decrypt the content of a blob through a generator."""
    modulo = offset % 16
    # Compute a file offset, might be lower than the real offset
    file_offset = offset - modulo if offset else 0

    end = offset + length if length else None

    algorithm = algorithms.AES(key)
    counter = counter_for_offset(offset)
    cipher = Cipher(algorithm=algorithm, mode=counter,
                    backend=default_backend())
    decryptor = cipher.decryptor()

    chunks_generator = storage.read_in_chunks(blob_id, offset=file_offset,
                                              chunk_size=10)

    for i, enc_chunk in chunks_generator:
        chunk = decryptor.update(enc_chunk)

        if end is not None:
            here = offset - modulo + i*10
            if end <= here + 10:
                chunk = chunk[:end - here]
                yield chunk
                break

        if i == 0:
            yield chunk[modulo:]
        else:
            yield chunk

    yield decryptor.finalize()
Exemplo n.º 18
0
class CommutativeCipher:
    """
    Encryption and decryption using a commutative cipher.
    """
    def __init__(self):
        key = os.urandom(32)
        iv = os.urandom(16)
        self.cipher = Cipher(algorithms.AES(key), modes.OFB(iv), backend=default_backend())


    def encrypt(self, plaintext, base64=False):
        """
        Encrypts a plaintext message and returns base 64 encoded ciphertext.
        If base64 is specified, decodes from base64 first.
        """
        plaintext = plaintext.encode(ENCODING)
        if base64: plaintext = decodebytes(plaintext)

        encryptor = self.cipher.encryptor()
        ciphertext = encryptor.update(plaintext) + encryptor.finalize()
        return encodebytes(ciphertext).decode(ENCODING)

    def decrypt(self, ciphertext, base64=False):
        """
        Decrypts base 64 encoded ciphertext and returns the plaintext message.

        If base64 is specified, provides result base64 encoded.
        """
        ciphertext = decodebytes(ciphertext.encode(ENCODING))

        decryptor = self.cipher.decryptor()
        plaintext = decryptor.update(ciphertext) + decryptor.finalize()

        if base64: plaintext = encodebytes(plaintext)
        return plaintext.decode(ENCODING)
Exemplo n.º 19
0
    def decrypt_payload(self, key, dest_path, chunksize=CHUNKSIZE):
        with open(self.enc_payload, 'rb') as infile:
            iv = infile.read(16)
            backend = default_backend()
            cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
            decryptor = cipher.decryptor()

            origsize = 0
            with open(self.payload, 'wb') as outfile:
                while True:
                    chunk = infile.read(chunksize)
                    if len(chunk) == 0:
                        break
                    plaintext = decryptor.update(chunk)
                    if origsize:
                        outfile.write(plaintext)
                    else:
                        origsize, pad = struct.unpack('<QQ', plaintext[0:16])
                        outfile.write(plaintext[16:])

                outfile.write(decryptor.finalize())
                outfile.truncate(origsize)

            archive = tarfile.open(self.payload)
            archive.extractall(dest_path)
            archive.close()
Exemplo n.º 20
0
    def _decrypt_data(self, data):
        assert self._encryption_key

        from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
        from cryptography.hazmat.backends import default_backend
        from binascii import a2b_base64

        key = self._encryption_key
        encoded_message = a2b_base64(data)

        version = encoded_message[0:1]
        tag = encoded_message[1:17]
        initialization_vector = encoded_message[17:29]
        encrypted_message = encoded_message[29:]

        if version != b"1":
            raise Exception("Invalid Version")

        cipher = Cipher(algorithms.AES(key),
                        modes.GCM(initialization_vector, tag),
                        backend=default_backend())
        decryptor = cipher.decryptor()

        decrypted = decryptor.update(encrypted_message) + decryptor.finalize()
        decrypted = decrypted.decode()

        return(decrypted)
Exemplo n.º 21
0
    def decrypt(self, ciphertext):
        '''
        The decrypt constructor takes the ciphertext string, sends it to
        the postProcess class to be chunked. The blocks are then decrypted
        and unpadded using the python cryptography library. Returns a
        ciphertext string.
        '''
        # Send the ciphertext string to be chunked
        ciphertext = self.postProcess(ciphertext)
        
        # Initilize the python cryptography ECB mode
        backend = default_backend()
        cipher = Cipher(algorithms.AES(self.key), modes.ECB(),
                backend = backend)
        decryptor = cipher.decryptor()

        # Loop through decrypt the ciphertext and then unpad.
        plaintextList = []
        if (len(ciphertext) == 1):
            plaintext = decryptor.update(ciphertext[0])
            unPaddedPt = self.unPad(plaintext)
            return unPaddedPt
        else:
            for i in range(0, len(ciphertext)):
                plaintext = decryptor.update(ciphertext[i])
                plaintextList.append(plaintext)
            paddedElement = self.unPad(plaintextList.pop(-1))
            plaintextList.append(paddedElement)
            return ''.join(plaintextList)
Exemplo n.º 22
0
 def decrypt(self, ciphertext):
     '''
     This decrypt constructor takes the ciphertext string, sends it to the
     postProcess class to be chunked. The blocks are sent to the python
     cryptography ECB mode for decryption. The first block is then xored
     with the IV. The remaining blocks are xored with the previous
     ciphertext in the list. The last element in the plaintextList is
     then unpadded.
     '''
     # Send the ciphertext string to be chunked
     ciphertext = self.postProcess(ciphertext)
     
     # Initilize the python cryptography ECB mode
     backend = default_backend()
     cipher = Cipher(algorithms.AES(self.key), modes.ECB(),
             backend = backend)
     decryptor = cipher.decryptor()
     
     # Loop through the ciphertext list, special treatment for block 1
     plaintextList = []
     for i in range(0, len(ciphertext)):
         if (i == 0):
             firstElement = decryptor.update(ciphertext[i])
             xor = xorData(self.iv, firstElement)
             firstPlaintext = xor.getXor()
             plaintextList.append(firstPlaintext)
         elif (i >= 1):
             nElement = decryptor.update(ciphertext[i])
             xor = xorData(ciphertext[i-1], nElement)
             nPlaintext = xor.getXor()
             plaintextList.append(nPlaintext)
     paddedElement = self.unPad(plaintextList.pop(-1))
     plaintextList.append(paddedElement)
     return ''.join(plaintextList)
Exemplo n.º 23
0
    def create_decryption_ctxt(self, key, iv, offset):
        """
        Creates a crypto context for decrypting

        :param key: 256-bit key
        :param iv: 128-bit iv or nonce used for decryption
        :param offset: offset into the message; used for range reads
        :returns: an instance of a decryptor
        """
        self.check_key(key)
        if offset < 0:
            raise ValueError('Offset must not be negative')
        if offset:
            # Adjust IV so that it is correct for decryption at offset.
            # The CTR mode offset is incremented for every AES block and taken
            # modulo 2^128.
            offset_blocks, offset_in_block = divmod(offset, self.iv_length)
            ivl = long(binascii.hexlify(iv), 16) + offset_blocks
            ivl %= 1 << algorithms.AES.block_size
            iv = str(bytearray.fromhex(format(
                ivl, '0%dx' % (2 * self.iv_length))))
        else:
            offset_in_block = 0

        engine = Cipher(algorithms.AES(key), modes.CTR(iv),
                        backend=self.backend)
        dec = engine.decryptor()
        # Adjust decryption boundary within current AES block
        dec.update('*' * offset_in_block)
        return dec
def aes_decrypt_legacy(payload, secret):
    """
    Legacy AES decryption (FROM INSECURE ENCRYPTION)!
    Return decrypted secret on success
    Return None on error
    """
    print "Falling back to legacy decryption"
    
    # DO NOT USE TO ENCRYPT
    # legacy hold-over for migrating to stronger encryption
    def ensure_length(secret):
        if len(secret) > 32:
            secret = secret[:32]

        elif len(secret) < 24:
            length = 24 - (len(secret) % 24)
            secret += chr(length)*length
        elif len(secret) > 24 and len(secret) < 32:
            length = 32 - (len(secret) % 32)
            secret += chr(length)*length

        return hexlify(secret)

    try:
        PADDING = '{'

        secret = ensure_length(secret)
        cipher = Cipher(algorithms.AES(unhexlify(secret)), modes.ECB(),
                        backend = default_backend())
        decryptor = cipher.decryptor()
        res = decryptor.update(base64.b64decode(payload)) + decryptor.finalize()
        res = res.rstrip(PADDING)
        return res
    except:
        return None
Exemplo n.º 25
0
def Symmetric_Decrypt(ciph_text, aes_key, iv):
   backend = default_backend()
   cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv),backend=backend)
   decryptor = cipher.decryptor()
   paddedClearText = decryptor.update(ciph_text) + decryptor.finalize()
   Clear_Text = Remove_Padding(paddedClearText)
   return Clear_Text
Exemplo n.º 26
0
    def decrypt_keymaterial(self, passphrase):
        if not self.encrypted:
            return  # pragma: no cover

        # Encryption/decryption of the secret data is done in CFB mode using
        # the key created from the passphrase and the Initial Vector from the
        # packet.  A different mode is used with V3 keys (which are only RSA)
        # than with other key formats.  (...)
        #
        # With V4 keys, a simpler method is used.  All secret MPI values are
        # encrypted in CFB mode, including the MPI bitcount prefix.

        for pkt in self.keypkts:
            # derive a key from our passphrase. If the passphrase is correct, this will be the right one...
            sessionkey = pkt.stokey.derive_key(passphrase)

            # instantiate the correct algorithm with the correct keylength
            if pkt.stokey.alg == SymmetricKeyAlgo.CAST5:
                alg = algorithms.CAST5(sessionkey)

            # attempt to decrypt this packet!
            cipher = Cipher(alg, modes.CFB(pkt.stokey.iv), backend=default_backend())
            decryptor = cipher.decryptor()

            pt = decryptor.update(pkt.enc_seckey_material) + decryptor.finalize()

            # check the hash to see if we decrypted successfully or not
            if pkt.stokey.id == 254:
                if not pt[-20:] == hashlib.new('sha1', pt[:-20]).digest():
                    raise PGPKeyDecryptionError("Passphrase was incorrect!")

                # parse decrypted key material into pkt.seckey_material
                pkt.seckey_material.parse(pt[:-20], pkt.header.tag, pkt.key_algorithm, sec=True)
                pkt.checksum = pt[-20:]
Exemplo n.º 27
0
    def __init__(self,
                 remote: Node,
                 privkey: datatypes.PrivateKey,
                 reader: asyncio.StreamReader,
                 writer: asyncio.StreamWriter,
                 aes_secret: bytes,
                 mac_secret: bytes,
                 egress_mac: PreImage,
                 ingress_mac: PreImage,
                 chaindb: AsyncChainDB,
                 network_id: int,
                 ) -> None:
        self._finished = asyncio.Event()
        self.remote = remote
        self.privkey = privkey
        self.reader = reader
        self.writer = writer
        self.base_protocol = P2PProtocol(self)
        self.chaindb = chaindb
        self.network_id = network_id
        self.sub_proto_msg_queue = asyncio.Queue()  # type: asyncio.Queue[Tuple[protocol.Command, protocol._DecodedMsgType]]  # noqa: E501
        self.cancel_token = CancelToken('Peer')

        self.egress_mac = egress_mac
        self.ingress_mac = ingress_mac
        # FIXME: Yes, the encryption is insecure, see: https://github.com/ethereum/devp2p/issues/32
        iv = b"\x00" * 16
        aes_cipher = Cipher(algorithms.AES(aes_secret), modes.CTR(iv), default_backend())
        self.aes_enc = aes_cipher.encryptor()
        self.aes_dec = aes_cipher.decryptor()
        mac_cipher = Cipher(algorithms.AES(mac_secret), modes.ECB(), default_backend())
        self.mac_enc = mac_cipher.encryptor().update
Exemplo n.º 28
0
    def decrypt(self, key, msg, b64decode=True):
        """Decrypts the provided ciphertext.

        The ciphertext can be optionally base64 encoded.

        Uses AES-128-CBC with an IV by default.

        :param key: The Encryption key.
        :param msg: the ciphetext, the first block is the IV

        :returns: the plaintext message, after padding is removed.
        """
        key = str.encode(get_valid_encryption_key(key))
        if b64decode:
            msg = base64.b64decode(msg)
        algo = self.algo(key)
        block_size_bytes = algo.block_size // 8
        iv = msg[:block_size_bytes]
        backend = backends.default_backend()
        cipher = Cipher(algo, modes.CBC(iv), backend=backend)
        decryptor = cipher.decryptor()
        padded = (decryptor.update(msg[block_size_bytes:]) +
                  decryptor.finalize())
        unpadder = padding.ANSIX923(algo.block_size).unpadder()
        plain = unpadder.update(padded) + unpadder.finalize()
        # The original padding algorithm was a slight variation on ANSI X.923,
        # where the size of the padding did not include the byte that tells
        # you the size of the padding. Therefore, we need to remove one extra
        # byte (which will be 0x00) when unpadding.
        return plain[:-1]
Exemplo n.º 29
0
 def parse_encrypted(self, part_len, data):
     if part_len != len(data):
         raise ProtocolError("Enc pkt size disaggrees with header.")
     if len(data) <= 38:
         raise ProtocolError("Truncated encrypted part.")
     uname_len, data = struct.unpack("!H", data[:2])[0], data[2:]
     if len(data) <= uname_len + 36:
         raise ProtocolError("Truncated encrypted part.")
     uname, data = data[:uname_len].decode(), data[uname_len:]
     if uname not in self.auth_db:
         raise ProtocolError("Couldn't decrypt, unknown user '%s'" % uname)
     iv, data = data[:16], data[16:]
     password = self.auth_db[uname].encode()
     key = sha256(password).digest()
     pad_bytes = 16 - (len(data) % 16)
     data += b'\0' * pad_bytes
     cipher = Cipher(algorithms.AES(key), modes.OFB(iv), backend=self.crypto_backend)
     decryptor = cipher.decryptor()
     data = decryptor.update(data)
     data = data[:-pad_bytes]
     tag, data = data[:20], data[20:]
     tag2 = sha1(data).digest()
     if not self._hashes_match(tag, tag2):
         raise ProtocolError("Bad checksum on enc pkt for '%s'" % uname)
     return data
Exemplo n.º 30
0
    def _load_block(self, i):
        if i == self.current_block:
            return

        self._flush_block()

        self.fp.seek(self.HEADER_SIZE + i * (self.IV_SIZE + self.block_size))
        iv = self.fp.read(self.IV_SIZE)

        if not iv:
            # Block does not exist, past end of file
            self.current_block = i
            self.block_cache = b""
            self.block_dirty = False
            return

        ciphertext = self.fp.read(self.block_size)
        cipher = Cipher(algorithms.AES(self.key), modes.CBC(iv), backend=backend)
        decryptor = cipher.decryptor()

        if (i+1)*self.block_size > self.data_size:
            size = self.data_size - i*self.block_size
        else:
            size = self.block_size

        self.current_block = i
        self.block_cache = (decryptor.update(ciphertext) + decryptor.finalize())[:size]
        self.block_dirty = False
Exemplo n.º 31
0
class MyCrypto(MyCommon):

    #------------ MyCrypto::init------------------------------------------------
    def __init__(self, log = None, console = None, key = None, iv = None):
        self.log = log
        self.console = console
        self.key = key          # bytes
        self.iv = iv            # bytes
        self.keysize = len(key) # in bytes
        self.blocksize = len(key) # in bytes

        self.debug = False
        # presently only AES-128 CBC mode is supported
        if self.keysize != 16:
            self.LogError("MyCrypto: WARNING: key size not 128: " + str(self.keysize))

        if len(self.iv) != 16:
            self.LogError("MyCrypto: WARNING: iv size not 128: " + str(self.keysize))
        try:
            self.backend = default_backend()
            self.cipher = Cipher(algorithms.AES(self.key), modes.CBC(self.iv), backend=self.backend)
            self.decryptor = self.cipher.decryptor()
            self.encryptor = self.cipher.encryptor()

        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:init: " + str(e1))
            sys.exit(1)
    #------------ MyCrypto::Encrypt---------------------------------------------
    # one block encrypt
    def Encrypt(self, cleartext, finalize = True):
        try:
            if len(cleartext) != self.keysize:
                self.LogError("MyCrypto:Encrypt: Blocksize mismatch: %d, %d" % (len(cyptertext), self.keysize))
                return None
            if finalize:
                retval =  self.encryptor.update(cleartext) + self.encryptor.finalize()
                self.Restart()
                return retval
            else:
                return self.encryptor.update(cleartext)
        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:Encrypt: " + str(e1))
            return None
    #------------ MyCrypto::Decrypt---------------------------------------------
    # one block decrypt
    def Decrypt(self, cyptertext, finalize = True):

        try:
            if len(cyptertext) != self.keysize:
                self.LogError("MyCrypto:Decrypt: Blocksize mismatch: %d, %d" % (len(cyptertext), self.keysize))
                return None

            if finalize:
                retval =  self.decryptor.update(cyptertext) + self.decryptor.finalize()
                self.Restart()
                return retval
            else:
                return self.decryptor.update(cyptertext)
        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:Decrypt: " + str(e1))
            return None

    #------------ MyCrypto::Restart---------------------------------------------
    def Restart(self, key = None, iv = None):

        try:
            if key != None:
                self.key = key
            if iv != None:
                self.iv = iv
            self.cipher = Cipher(algorithms.AES(self.key), modes.CBC(self.iv), backend=self.backend)
            self.decryptor = self.cipher.decryptor()
            self.encryptor = self.cipher.encryptor()
        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:Restart: " + str(e1))
            return None

    #------------ MyCrypto::EncryptBuff-----------------------------------------
    # multiple block encrypt
    def EncryptBuff(self, plaintext_buff, pad_zero = True):
        try:

            if plaintext_buff == None:
                self.LogError("MyCrypto:EncryptBuff: Error: invalid buffer! ")
                return None
            if len(plaintext_buff) == 0:
                self.LogError("MyCrypto:EncryptBuff: Warning: plaintext buffer size is invalid")
                return None

            if len(plaintext_buff) % self.blocksize:
                self.LogDebug("MyCrypto:EncryptBuff: WARNING: buffer is not a multipe of blocksize")
            index1 = 0
            index2 = self.blocksize
            ct_buf = b""
            while(True):
                if index2 > len(plaintext_buff):
                    # remaining bytes are not block size
                    buff = plaintext_buff[index1:]
                    if pad_zero:
                        for i in range(0,(self.blocksize - len(buff))):
                            buff += b'\0'
                        ct_buf += self.Encrypt(buff)
                        break
                    else:
                        # append plain text to cryptotext buffer
                        ct_buf += buff
                    break
                buff = plaintext_buff[index1:index2]
                ct_buf += self.Encrypt(buff)
                index1 += self.blocksize
                index2 += self.blocksize
                if index1 == len(plaintext_buff):
                    break
            return ct_buf

        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:EncryptBuff: " + str(e1))
            return None

    #------------ MyCrypto::DecryptBuff-----------------------------------------
    # multiple block decrypt
    def DecryptBuff(self, crypttext_buff, pad_zero = True):
        try:

            if crypttext_buff == None:
                self.LogError("MyCrypto:DecryptBuff: Error: invalid buffer! ")
                return None
            if len(crypttext_buff) < self.blocksize:
                self.LogError("MyCrypto:DecryptBuff: Error: crypttext buffer size less than blocksize")
                return None

            if len(crypttext_buff) % self.blocksize:
                self.LogDebug("MyCrypto:DecryptBuff: WARNING: buffer is not a multipe of blocksize")

            index1 = 0
            index2 = self.blocksize
            pt_buf = b""
            while(True):
                if index2 > len(crypttext_buff):
                    # remaining bytes are not block size
                    buff = crypttext_buff[index1:]
                    if pad_zero:
                        for i in range(0,(self.blocksize - len(buff))):
                            buff += b'\0'
                        pt_buf += self.Decrypt(buff)
                        break
                    else:
                        # append plain text to cryptotext buffer
                        pt_buf += buff
                    break
                buff = crypttext_buff[index1:index2]
                pt_buf += self.Decrypt(buff)
                index1 += self.blocksize
                index2 += self.blocksize
                if index1 == len(crypttext_buff):
                    break

            return pt_buf

        except Exception as e1:
            self.LogErrorLine("Error in MyCrypto:EncryptBuff: " + str(e1))
            return None
# create a mutable array to hold the bytes
data = bytearray(blocksize)
file = open(mydata, 'rb')
file2 = open(mydata2, 'wb')
#path = os.path.abspath(fname)
#print(mydata)
mydata_pad = padder.update(mydata) + padder.finalize()

print(mydata_pad.hex())  # print padded dummy data
#ciphertext = encryptor.update(mydata) + encryptor.finalize()
ciphertext = encryptor.update(
    mydata_pad) + encryptor.finalize()  # padded ciphertext
print(ciphertext.hex())

#  Create our dummy that will be decrypted
decryptor = cipher.decryptor(
)  #  Decryptor object that decrypts ciphertext data
plaintext = decryptor.update(ciphertext) + decryptor.finalize()

# loop until done
while True:
    # read block from source file
    num = file.readinto(data)
    # adjust totalsize
    totalsize += num
    # print data, assuming text data
    #print(num,data)
    # use following if raw binary data
    # print(num,data.hex())
    # check if full block read
    if num == blocksize:
        # write full block to destination
Exemplo n.º 33
0
class _BlockCipher(six.with_metaclass(_BlockCipherMetaclass, object)):
    type = "block"

    def __init__(self, key=None, iv=None):
        self.ready = {"key": True, "iv": True}
        if key is None:
            self.ready["key"] = False
            if hasattr(self, "expanded_key_len"):
                l = self.expanded_key_len
            else:
                l = self.key_len
            key = b"\0" * l
        if not iv:
            self.ready["iv"] = False
            iv = b"\0" * self.block_size

        # we use super() in order to avoid any deadlock with __setattr__
        super(_BlockCipher, self).__setattr__("key", key)
        super(_BlockCipher, self).__setattr__("iv", iv)

        self._cipher = Cipher(self.pc_cls(key),
                              self.pc_cls_mode(iv),
                              backend=backend)

    def __setattr__(self, name, val):
        if name == "key":
            if self._cipher is not None:
                self._cipher.algorithm.key = val
            self.ready["key"] = True
        elif name == "iv":
            if self._cipher is not None:
                self._cipher.mode._initialization_vector = val
            self.ready["iv"] = True
        super(_BlockCipher, self).__setattr__(name, val)

    def encrypt(self, data):
        """
        Encrypt the data. Also, update the cipher iv. This is needed for SSLv3
        and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.post_build().
        """
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        encryptor = self._cipher.encryptor()
        tmp = encryptor.update(data) + encryptor.finalize()
        self.iv = tmp[-self.block_size:]
        return tmp

    def decrypt(self, data):
        """
        Decrypt the data. Also, update the cipher iv. This is needed for SSLv3
        and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.pre_dissect().
        If we lack the key, we raise a CipherError which contains the input.
        """
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        decryptor = self._cipher.decryptor()
        tmp = decryptor.update(data) + decryptor.finalize()
        self.iv = data[-self.block_size:]
        return tmp

    def snapshot(self):
        c = self.__class__(self.key, self.iv)
        c.ready = self.ready.copy()
        return c
Exemplo n.º 34
0
"""
Created on Sat Mar 04 20:38:51 2017

@author: Pericle
"""

import sys
import binascii
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

block = algorithms.AES.block_size/8

filename = raw_input('Type the file to decrypt: ')
with open(filename, 'rb') as f:
    iv = f.read(block)
    ciphertext = f.read()
if len(ciphertext) % block != 0:
    sys.exit('The file must be multiple of ' + str(block) + ' bytes.')

key_hex = raw_input('Type the key in ' + str(2*block) + ' hexadecimal digits: ')
key = binascii.unhexlify(key_hex)

cipher = Cipher(algorithms.AES(key), modes.CBC(iv), default_backend())
ctx = cipher.decryptor()
plaintext = ctx.update(ciphertext) + ctx.finalize()

with open(filename + '.dec', 'wb') as f:
    f.write(plaintext)
print('Decrypted file: ' + filename + '.dec')
Exemplo n.º 35
0
class GLSecureTemporaryFile(_TemporaryFileWrapper):
    """
    WARNING!
    You can't use this File object like a normal file object,
    check .read and .write!
    """

    last_action = 'init'

    def __init__(self, filedir):
        """
        filedir: dir target to keep GL.
        """

        self.create_key()

        # XXX remind enhance file name with incremental number
        self.filepath = os.path.join(filedir, "%s.aes" % self.key_id)

        log.debug("++ Creating %s filetmp" % self.filepath)

        self.file = open(self.filepath, 'w+b')

        # last argument is 'True' because the file has to be deleted on .close()
        _TemporaryFileWrapper.__init__(self, self.file, self.filepath, True)

    def initialize_cipher(self):
        self.cipher = Cipher(algorithms.AES(self.key),
                             modes.CTR(self.key_counter_nonce),
                             backend=crypto_backend)
        self.encryptor = self.cipher.encryptor()
        self.decryptor = self.cipher.decryptor()

    def create_key(self):
        """
        Create the AES Key to encrypt uploaded file.
        """
        self.key = os.urandom(GLSetting.AES_key_size)

        self.key_id = xeger(GLSetting.AES_key_id_regexp)
        self.keypath = os.path.join(
            GLSetting.ramdisk_path,
            "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id))

        while os.path.isfile(self.keypath):
            self.key_id = xeger(GLSetting.AES_key_id_regexp)
            self.keypath = os.path.join(
                GLSetting.ramdisk_path,
                "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id))

        self.key_counter_nonce = os.urandom(GLSetting.AES_counter_nonce)
        self.initialize_cipher()

        saved_struct = {
            'key': self.key,
            'key_counter_nonce': self.key_counter_nonce
        }

        log.debug("Key initialization at %s" % self.keypath)

        with open(self.keypath, 'w') as kf:
            pickle.dump(saved_struct, kf)

        if not os.path.isfile(self.keypath):
            log.err("Unable to write keyfile %s" % self.keypath)
            raise Exception("Unable to write keyfile %s" % self.keypath)

    def avoid_delete(self):
        log.debug("Avoid delete on: %s " % self.filepath)
        self.delete = False

    def write(self, data):
        """
        The last action is kept track because the internal status
        need to track them. read below read()
        """

        assert (self.last_action != 'read'), "you can write after read!"

        self.last_action = 'write'
        try:
            if isinstance(data, unicode):
                data = data.encode('utf-8')

            self.file.write(self.encryptor.update(data))
        except Exception as wer:
            log.err("Unable to write() in GLSecureTemporaryFile: %s" %
                    wer.message)
            raise wer

    def close(self):
        if any(x in self.file.mode for x in 'wa') and not self.close_called:
            self.file.write(self.encryptor.finalize())
        return _TemporaryFileWrapper.close(self)

    def read(self, c=None):
        """
        The first time 'read' is called after a write, is automatically seek(0)
        """
        if self.last_action == 'write':
            self.seek(0, 0)  # this is a trick just to misc write and read
            self.initialize_cipher()
            log.debug("First seek on %s" % self.filepath)
            self.last_action = 'read'

        if c is None:
            return self.decryptor.update(self.file.read())
        else:
            return self.decryptor.update(self.file.read(c))
Exemplo n.º 36
0
def _flash_encryption_operation(output_file, input_file, flash_address, keyfile, flash_crypt_conf, do_decrypt):
    key = _load_hardware_key(keyfile)

    if flash_address % 16 != 0:
        raise esptool.FatalError("Starting flash address 0x%x must be a multiple of 16" % flash_address)

    if flash_crypt_conf == 0:
        print("WARNING: Setting FLASH_CRYPT_CONF to zero is not recommended")

    if esptool.PYTHON2:
        tweak_range = _flash_encryption_tweak_range(flash_crypt_conf)
    else:
        tweak_range = _flash_encryption_tweak_range_bits(flash_crypt_conf)
        key = int.from_bytes(key, byteorder='big', signed=False)

    backend = default_backend()

    cipher = None
    block_offs = flash_address
    while True:
        block = input_file.read(16)
        if len(block) == 0:
            break
        elif len(block) < 16:
            if do_decrypt:
                raise esptool.FatalError("Data length is not a multiple of 16 bytes")
            pad = 16 - len(block)
            block = block + os.urandom(pad)
            print("Note: Padding with %d bytes of random data (encrypted data must be multiple of 16 bytes long)" % pad)

        if block_offs % 32 == 0 or cipher is None:
            # each bit of the flash encryption key is XORed with tweak bits derived from the offset of 32 byte block of flash
            block_key = _flash_encryption_tweak_key(key, block_offs, tweak_range)

            if cipher is None:  # first pass
                cipher = Cipher(algorithms.AES(block_key), modes.ECB(), backend=backend)

                # note AES is used inverted for flash encryption, so
                # "decrypting" flash uses AES encrypt algorithm and vice
                # versa. (This does not weaken AES.)
                actor = cipher.encryptor() if do_decrypt else cipher.decryptor()
            else:
                # performance hack: changing the key using pyca-cryptography API requires recreating
                # 'actor'. With openssl backend, this re-initializes the openssl cipher context. To save some time,
                # manually call EVP_CipherInit_ex() in the openssl backend to update the key.
                # If it fails, fall back to recreating the entire context via public API.
                try:
                    backend = actor._ctx._backend
                    res = backend._lib.EVP_CipherInit_ex(
                        actor._ctx._ctx,
                        backend._ffi.NULL,
                        backend._ffi.NULL,
                        backend._ffi.from_buffer(block_key),
                        backend._ffi.NULL,
                        actor._ctx._operation,
                    )
                    backend.openssl_assert(res != 0)
                except AttributeError:
                    # backend is not an openssl backend, or implementation has changed: fall back to the slow safe version
                    cipher.algorithm.key = block_key
                    actor = cipher.encryptor() if do_decrypt else cipher.decryptor()

        block = block[::-1]  # reverse input block byte order
        block = actor.update(block)

        output_file.write(block[::-1])  # reverse output block byte order
        block_offs += 16
Exemplo n.º 37
0
    def decrypt_file(metadata, encryption_material, in_filename,
                     chunk_size=block_size * 4 * 1024, tmp_dir=None):
        """Decrypts a file and stores the output in the temporary directory.

        Args:
            metadata: The file's metadata input.
            encryption_material: The file's encryption material.
            in_filename: The name of the input file.
            chunk_size: The size of read chunks (Default value = block_size * 4 * 1024).
            tmp_dir: Temporary directory to use, optional (Default value = None).

        Returns:
            The decrypted file's location.
        """
        logger = getLogger(__name__)
        use_openssl_only = os.getenv('SF_USE_OPENSSL_ONLY', 'False') == 'True'
        key_base64 = metadata.key
        iv_base64 = metadata.iv
        decoded_key = base64.standard_b64decode(
            encryption_material.query_stage_master_key)
        key_bytes = base64.standard_b64decode(key_base64)
        iv_bytes = base64.standard_b64decode(iv_base64)

        if not use_openssl_only:
            key_cipher = AES.new(key=decoded_key, mode=AES.MODE_ECB)
            file_key = PKCS5_UNPAD(key_cipher.decrypt(key_bytes))
            data_cipher = AES.new(key=file_key, mode=AES.MODE_CBC, IV=iv_bytes)
        else:
            backend = default_backend()
            cipher = Cipher(algorithms.AES(decoded_key), modes.ECB(), backend=backend)
            decryptor = cipher.decryptor()
            file_key = PKCS5_UNPAD(decryptor.update(key_bytes) + decryptor.finalize())
            cipher = Cipher(algorithms.AES(file_key), modes.CBC(iv_bytes), backend=backend)
            decryptor = cipher.decryptor()

        temp_output_fd, temp_output_file = tempfile.mkstemp(
            text=False, dir=tmp_dir,
            prefix=os.path.basename(in_filename) + "#")
        total_file_size = 0
        prev_chunk = None
        logger.debug('encrypted file: %s, tmp file: %s',
                     in_filename, temp_output_file)
        with open(in_filename, 'rb') as infile:
            with os.fdopen(temp_output_fd, 'wb') as outfile:
                while True:
                    chunk = infile.read(chunk_size)
                    if len(chunk) == 0:
                        break
                    total_file_size += len(chunk)
                    if not use_openssl_only:
                        d = data_cipher.decrypt(chunk)
                    else:
                        d = decryptor.update(chunk)
                    outfile.write(d)
                    prev_chunk = d
                if prev_chunk is not None:
                    total_file_size -= PKCS5_OFFSET(prev_chunk)
                if use_openssl_only:
                    outfile.write(decryptor.finalize())
                outfile.truncate(total_file_size)
        return temp_output_file
Exemplo n.º 38
0
def decrypt_func(key, iv, ct):
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    decryptor = cipher.decryptor()
    message = decryptor.update(ct) + decryptor.finalize()
    message = depadding(message.decode('ascii'))
    return message
Exemplo n.º 39
0
    def test_extensions(self, ):

        salt1 = b"\x5a" * 32
        salt2 = b"\x96" * 32
        salt3 = b"\x03" * 32

        # self.testReset()

        with Test("Get info has hmac-secret"):
            info = self.ctap.get_info()
            assert "hmac-secret" in info.extensions

        reg = self.testMC(
            "Send MC with hmac-secret ext set to true, expect SUCCESS",
            cdh,
            rp,
            user,
            key_params,
            expectedError=CtapError.ERR.SUCCESS,
            other={
                "extensions": {
                    "hmac-secret": True
                },
                "options": {
                    "rk": True
                }
            },
        )

        with Test(
                "Check 'hmac-secret' is set to true in auth_data extensions"):
            assert reg.auth_data.extensions
            assert "hmac-secret" in reg.auth_data.extensions
            assert reg.auth_data.extensions["hmac-secret"] == True

        reg = self.testMC(
            "Send MC with fake extension set to true, expect SUCCESS",
            cdh,
            rp,
            user,
            key_params,
            expectedError=CtapError.ERR.SUCCESS,
            other={"extensions": {
                "tetris": True
            }},
        )

        with Test("Get shared secret"):
            key_agreement, shared_secret = (
                self.client.pin_protocol._init_shared_secret())
            cipher = Cipher(
                algorithms.AES(shared_secret),
                modes.CBC(b"\x00" * 16),
                default_backend(),
            )

        def get_salt_params(salts):
            enc = cipher.encryptor()
            salt_enc = b""
            for salt in salts:
                salt_enc += enc.update(salt)
            salt_enc += enc.finalize()

            salt_auth = hmac_sha256(shared_secret, salt_enc)[:16]
            return salt_enc, salt_auth

        for salt_list in ((salt1, ), (salt1, salt2)):
            salt_enc, salt_auth = get_salt_params(salt_list)

            auth = self.testGA(
                "Send GA request with %d salts hmac-secret, expect success" %
                len(salt_list),
                rp["id"],
                cdh,
                other={
                    "extensions": {
                        "hmac-secret": {
                            1: key_agreement,
                            2: salt_enc,
                            3: salt_auth
                        }
                    }
                },
                expectedError=CtapError.ERR.SUCCESS,
            )

            with Test(
                    "Check that hmac-secret is in auth_data extensions and has %d bytes"
                    % (len(salt_list) * 32)):
                ext = auth.auth_data.extensions
                assert ext
                assert "hmac-secret" in ext
                assert isinstance(ext["hmac-secret"], bytes)
                assert len(ext["hmac-secret"]) == len(salt_list) * 32

            with Test("Check that shannon_entropy of hmac-secret is good"):
                ext = auth.auth_data.extensions
                dec = cipher.decryptor()
                key = dec.update(ext["hmac-secret"]) + dec.finalize()

                print(shannon_entropy(ext["hmac-secret"]))
                if len(salt_list) == 1:
                    assert shannon_entropy(ext["hmac-secret"]) > 4.6
                    assert shannon_entropy(key) > 4.6
                if len(salt_list) == 2:
                    assert shannon_entropy(ext["hmac-secret"]) > 5.4
                    assert shannon_entropy(key) > 5.4

        salt_enc, salt_auth = get_salt_params((salt3, ))

        auth = self.testGA(
            "Send GA request with hmac-secret missing keyAgreement, expect error",
            rp["id"],
            cdh,
            other={"extensions": {
                "hmac-secret": {
                    2: salt_enc,
                    3: salt_auth
                }
            }},
        )
        auth = self.testGA(
            "Send GA request with hmac-secret missing saltAuth, expect MISSING_PARAMETER",
            rp["id"],
            cdh,
            other={
                "extensions": {
                    "hmac-secret": {
                        1: key_agreement,
                        2: salt_enc
                    }
                }
            },
            expectedError=CtapError.ERR.MISSING_PARAMETER,
        )
        auth = self.testGA(
            "Send GA request with hmac-secret missing saltEnc, expect MISSING_PARAMETER",
            rp["id"],
            cdh,
            other={
                "extensions": {
                    "hmac-secret": {
                        1: key_agreement,
                        3: salt_auth
                    }
                }
            },
            expectedError=CtapError.ERR.MISSING_PARAMETER,
        )

        bad_auth = list(salt_auth[:])
        bad_auth[len(bad_auth) // 2] = bad_auth[len(bad_auth) // 2] ^ 1
        bad_auth = bytes(bad_auth)

        auth = self.testGA(
            "Send GA request with hmac-secret containing bad saltAuth, expect EXTENSION_FIRST",
            rp["id"],
            cdh,
            other={
                "extensions": {
                    "hmac-secret": {
                        1: key_agreement,
                        2: salt_enc,
                        3: bad_auth
                    }
                }
            },
            expectedError=CtapError.ERR.EXTENSION_FIRST,
        )

        salt4 = b"\x5a" * 16
        salt5 = b"\x96" * 64
        for salt_list in ((salt4, ), (salt4, salt5)):
            salt_enc, salt_auth = get_salt_params(salt_list)

            salt_auth = hmac_sha256(shared_secret, salt_enc)[:16]
            auth = self.testGA(
                "Send GA request with incorrect salt length %d, expect INVALID_LENGTH"
                % len(salt_enc),
                rp["id"],
                cdh,
                other={
                    "extensions": {
                        "hmac-secret": {
                            1: key_agreement,
                            2: salt_enc,
                            3: salt_auth
                        }
                    }
                },
                expectedError=CtapError.ERR.INVALID_LENGTH,
            )
Exemplo n.º 40
0
class device:
    """Controls a Broadlink device."""
    def __init__(
        self,
        host: Tuple[str, int],
        mac: Union[bytes, str],
        devtype: int,
        timeout: int = 10,
        name: str = None,
        model: str = None,
        manufacturer: str = None,
        is_locked: bool = None,
    ) -> None:
        """Initialize the controller."""
        self.host = host
        self.mac = mac.encode() if isinstance(mac, str) else mac
        self.devtype = devtype if devtype is not None else 0x272a
        self.timeout = timeout
        self.name = name
        self.model = model
        self.manufacturer = manufacturer
        self.is_locked = is_locked
        self.count = random.randrange(0xffff)
        self.iv = bytes([
            0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba,
            0x69, 0x5a, 0x2e, 0x6f, 0x58
        ])
        self.id = bytes(4)
        self.type = "Unknown"
        self.lock = threading.Lock()

        self.aes = None
        key = bytes([
            0x09, 0x76, 0x28, 0x34, 0x3f, 0xe9, 0x9e, 0x23, 0x76, 0x5c, 0x15,
            0x13, 0xac, 0xcf, 0x8b, 0x02
        ])
        self.update_aes(key)

    def update_aes(self, key: bytes) -> None:
        """Update AES."""
        self.aes = Cipher(algorithms.AES(key),
                          modes.CBC(self.iv),
                          backend=default_backend())

    def encrypt(self, payload: bytes) -> bytes:
        """Encrypt the payload."""
        encryptor = self.aes.encryptor()
        return encryptor.update(payload) + encryptor.finalize()

    def decrypt(self, payload: bytes) -> bytes:
        """Decrypt the payload."""
        decryptor = self.aes.decryptor()
        return decryptor.update(payload) + decryptor.finalize()

    def auth(self) -> bool:
        """Authenticate to the device."""
        payload = bytearray(0x50)
        payload[0x04] = 0x31
        payload[0x05] = 0x31
        payload[0x06] = 0x31
        payload[0x07] = 0x31
        payload[0x08] = 0x31
        payload[0x09] = 0x31
        payload[0x0a] = 0x31
        payload[0x0b] = 0x31
        payload[0x0c] = 0x31
        payload[0x0d] = 0x31
        payload[0x0e] = 0x31
        payload[0x0f] = 0x31
        payload[0x10] = 0x31
        payload[0x11] = 0x31
        payload[0x12] = 0x31
        payload[0x1e] = 0x01
        payload[0x2d] = 0x01
        payload[0x30] = ord('T')
        payload[0x31] = ord('e')
        payload[0x32] = ord('s')
        payload[0x33] = ord('t')
        payload[0x34] = ord(' ')
        payload[0x35] = ord(' ')
        payload[0x36] = ord('1')

        response = self.send_packet(0x65, payload)
        check_error(response[0x22:0x24])
        payload = self.decrypt(response[0x38:])

        key = payload[0x04:0x14]
        if len(key) % 16 != 0:
            return False

        self.id = payload[0x03::-1]
        self.update_aes(key)
        return True

    def hello(self, local_ip_address=None) -> bool:
        """Send a hello message to the device.

        Device information is checked before updating name and lock status.
        """
        responses = scan(
            timeout=self.timeout,
            local_ip_address=local_ip_address,
            discover_ip_address=self.host[0],
            discover_ip_port=self.host[1],
        )
        try:
            devtype, host, mac, name, is_locked = next(responses)
        except StopIteration:
            raise exception(-4000)  # Network timeout.

        if (devtype, host, mac) != (self.devtype, self.host, self.mac):
            raise exception(-2040)  # Device information is not intact.

        self.name = name
        self.is_locked = is_locked
        return True

    def get_fwversion(self) -> int:
        """Get firmware version."""
        packet = bytearray([0x68])
        response = self.send_packet(0x6a, packet)
        check_error(response[0x22:0x24])
        payload = self.decrypt(response[0x38:])
        return payload[0x4] | payload[0x5] << 8

    def set_name(self, name: str) -> None:
        """Set device name."""
        packet = bytearray(4)
        packet += name.encode('utf-8')
        packet += bytearray(0x50 - len(packet))
        packet[0x43] = bool(self.is_locked)
        response = self.send_packet(0x6a, packet)
        check_error(response[0x22:0x24])
        self.name = name

    def set_lock(self, state: bool) -> None:
        """Lock/unlock the device."""
        packet = bytearray(4)
        packet += self.name.encode('utf-8')
        packet += bytearray(0x50 - len(packet))
        packet[0x43] = bool(state)
        response = self.send_packet(0x6a, packet)
        check_error(response[0x22:0x24])
        self.is_locked = bool(state)

    def get_type(self) -> str:
        """Return device type."""
        return self.type

    def send_packet(self, command: int, payload: bytes) -> bytes:
        """Send a packet to the device."""
        self.count = (self.count + 1) & 0xffff
        packet = bytearray(0x38)
        packet[0x00] = 0x5a
        packet[0x01] = 0xa5
        packet[0x02] = 0xaa
        packet[0x03] = 0x55
        packet[0x04] = 0x5a
        packet[0x05] = 0xa5
        packet[0x06] = 0xaa
        packet[0x07] = 0x55
        packet[0x24] = self.devtype & 0xff
        packet[0x25] = self.devtype >> 8
        packet[0x26] = command
        packet[0x28] = self.count & 0xff
        packet[0x29] = self.count >> 8
        packet[0x2a] = self.mac[5]
        packet[0x2b] = self.mac[4]
        packet[0x2c] = self.mac[3]
        packet[0x2d] = self.mac[2]
        packet[0x2e] = self.mac[1]
        packet[0x2f] = self.mac[0]
        packet[0x30] = self.id[3]
        packet[0x31] = self.id[2]
        packet[0x32] = self.id[1]
        packet[0x33] = self.id[0]

        # pad the payload for AES encryption
        padding = (16 - len(payload)) % 16
        if padding:
            payload = bytearray(payload)
            payload += bytearray(padding)

        checksum = sum(payload, 0xbeaf) & 0xffff
        packet[0x34] = checksum & 0xff
        packet[0x35] = checksum >> 8

        payload = self.encrypt(payload)
        for i in range(len(payload)):
            packet.append(payload[i])

        checksum = sum(packet, 0xbeaf) & 0xffff
        packet[0x20] = checksum & 0xff
        packet[0x21] = checksum >> 8

        start_time = time.time()
        with self.lock:
            cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

            while True:
                try:
                    cs.sendto(packet, self.host)
                    cs.settimeout(1)
                    resp, _ = cs.recvfrom(2048)
                    break
                except socket.timeout:
                    if (time.time() - start_time) > self.timeout:
                        cs.close()
                        raise exception(-4000)  # Network timeout.
            cs.close()

        if len(resp) < 0x30:
            raise exception(-4007)  # Length error.

        checksum = resp[0x20] | (resp[0x21] << 8)
        if sum(resp, 0xbeaf) - sum(resp[0x20:0x22]) & 0xffff != checksum:
            raise exception(-4008)  # Checksum error.

        return resp
Exemplo n.º 41
0
    def _download(self, url, file_name):
        cookies = self.kwargs.get("cookies", None)
        start_time = time.time()
        m3u8 = M3U8(self.http.request("get", url, cookies=cookies).text)
        key = None

        def random_iv():
            return os.urandom(16)

        file_d = output(file_name[0], self.config, file_name[1])
        if file_d is None:
            return

        hls_time_stamp = self.kwargs.pop("hls_time_stamp", False)
        decryptor = None
        size_media = len(m3u8.media_segment)
        eta = ETA(size_media)
        total_duration = 0
        duration = 0
        max_duration = 0
        for index, i in enumerate(m3u8.media_segment):
            if "duration" in i["EXTINF"]:
                duration = i["EXTINF"]["duration"]
                max_duration = max(max_duration, duration)
                total_duration += duration
            item = get_full_url(i["URI"], url)

            if not self.config.get("silent"):
                if self.config.get("live"):
                    progressbar(
                        size_media, index + 1, "".join([
                            "DU: ",
                            str(timedelta(seconds=int(total_duration)))
                        ]))
                else:
                    eta.increment()
                    progressbar(size_media, index + 1,
                                "".join(["ETA: ", str(eta)]))

            data = self.http.request("get", item, cookies=cookies)
            if data.status_code == 404:
                break
            data = data.content
            if m3u8.encrypted:
                headers = {}
                if self.keycookie:
                    keycookies = self.keycookie
                else:
                    keycookies = cookies
                if self.authorization:
                    headers["authorization"] = self.authorization

                # Update key/decryptor
                if "EXT-X-KEY" in i:
                    keyurl = get_full_url(i["EXT-X-KEY"]["URI"], url)
                    if keyurl and keyurl[:4] == "skd:":
                        raise HLSException(keyurl,
                                           "Can't decrypt beacuse of DRM")
                    key = self.http.request("get",
                                            keyurl,
                                            cookies=keycookies,
                                            headers=headers).content
                    iv = binascii.unhexlify(i["EXT-X-KEY"]["IV"][2:].zfill(
                        32)) if "IV" in i["EXT-X-KEY"] else random_iv()
                    backend = default_backend()
                    cipher = Cipher(algorithms.AES(key),
                                    modes.CBC(iv),
                                    backend=backend)
                    decryptor = cipher.decryptor()

                if decryptor:
                    data = decryptor.update(data)
                else:
                    raise ValueError(
                        "No decryptor found for encrypted hls steam.")

            file_d.write(data)

            if self.config.get(
                    "capture_time"
            ) > 0 and total_duration >= self.config.get("capture_time") * 60:
                break

            if (size_media == (index + 1)) and self.config.get("live"):
                sleep_int = (start_time + max_duration * 2) - time.time()
                if sleep_int > 0:
                    time.sleep(sleep_int)

                size_media_old = size_media
                while size_media_old == size_media:
                    start_time = time.time()

                    if hls_time_stamp:
                        end_time_stamp = (datetime.utcnow() - timedelta(
                            minutes=1, seconds=max_duration * 2)).replace(
                                microsecond=0)
                        start_time_stamp = end_time_stamp - timedelta(
                            minutes=1)

                        base_url = url.split(".m3u8")[0]
                        url = "{}.m3u8?in={}&out={}?".format(
                            base_url, start_time_stamp.isoformat(),
                            end_time_stamp.isoformat())

                    new_m3u8 = M3U8(
                        self.http.request("get", url, cookies=cookies).text)
                    for n_m3u in new_m3u8.media_segment:
                        if not any(d["URI"] == n_m3u["URI"]
                                   for d in m3u8.media_segment):
                            m3u8.media_segment.append(n_m3u)

                    size_media = len(m3u8.media_segment)

                    if size_media_old == size_media:
                        time.sleep(max_duration)

        file_d.close()
        if not self.config.get("silent"):
            progress_stream.write("\n")
        self.finished = True
Exemplo n.º 42
0
class TCPConnection(Packet):
    def __init__(self, addr, debug=False, timeout=10):
        Packet.__init__(self)
        self.encrypt = False
        self.debug = debug
        self.compression_threshold = None
        self.socket = socket.create_connection(addr, timeout=timeout)

    def read(self, length):
        result = bytearray()
        while len(result) < length:
            new = self.socket.recv(length - len(result))
            if len(new) == 0:
                raise IOError("Server didn't respond with information!")
            result.extend(new)
        if self.encrypt:
            result = bytearray(self.decryptor.update(bytes(result)))
        return result

    def write(self, data):
        self.socket.sendall(data)

    def receive_packet(self):
        packet_length = self.read_varint()
        packet_in = Packet()
        raw_data = self.read(packet_length)

        # Decompress if needed
        if self.compression_threshold is not None:
            raw_packet = Packet()
            raw_packet.receive(raw_data)
            data_length = raw_packet.read_varint()
            raw_data = raw_packet.read(len(raw_data))
            if data_length > 0:
                raw_data = zlib.decompress(raw_data)
        packet_in.receive(raw_data)
        return packet_in

    def send_packet(self, packet_out):
        # Compress if needed
        if self.compression_threshold is not None:
            data_length = len(packet_out.sent)
            raw_packet = packet_out.flush()
            if data_length < self.compression_threshold:
                packet_out.write_varint(0)
                packet_out.write(raw_packet)
            else:
                raw_packet = zlib.compress(raw_packet)
                packet_out.write_varint(len(raw_packet))
                packet_out.write(raw_packet)

        packet_data = packet_out.flush()
        packet_out.write_varint(len(packet_data))
        packet_out.write(packet_data)

        if self.encrypt:
            packet_data = packet_out.flush()
            packet_out.write(
                bytearray(self.encryptor.update(bytes(packet_data))))

        if self.debug:
            print('Sending packet: ' + str(packet_out.sent))
        self.write(packet_out.flush())

    # Configures the encryption from given key
    def configure_encryption(self, secret_key):
        self.cipher = Cipher(algorithms.AES(secret_key),
                             modes.CFB8(secret_key),
                             backend=default_backend())
        self.encryptor = self.cipher.encryptor()
        self.decryptor = self.cipher.decryptor()
        self.encrypt = True
        print('Encryption enabled')

    def close(self):
        self.socket.close()

    def __del__(self):
        self.socket.close()
# NEVER USE: ECB is not secure!
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os

key = os.urandom(16)
aesCipher = Cipher(algorithms.AES(key),
                   modes.ECB(),
                   backend=default_backend())
aesEncryptor = aesCipher.encryptor()
aesDecryptor = aesCipher.decryptor()

print(aesEncryptor.update(b'0000000000000000'))
print(aesDecryptor.update(b'0000000000000000'))
if(aesCipher.decryptor().update(
    aesCipher.encryptor().update(b'0000000000000000')) ==
        b'0000000000000000'):
    print("[PASS]")
else:
    print("[FAIL]")
Exemplo n.º 44
0
    def __init__(
        self,
        remote: Node,
        privkey: datatypes.PrivateKey,
        connection: PeerConnection,
        context: BasePeerContext,
        inbound: bool = False,
        token: CancelToken = None,
        listen_port: int = 30303,
    ) -> None:
        super().__init__(token)

        # Any contextual information the peer may need.
        self.context = context

        # The `Node` that this peer is connected to
        self.remote = remote

        # The private key this peer uses for identification and encryption.
        self.privkey = privkey

        # Networking reader and writer objects for communication
        self.reader = connection.reader
        self.writer = connection.writer
        self.base_protocol = P2PProtocol(self)

        # Flag indicating whether the connection this peer represents was
        # established from a dial-out or dial-in (True: dial-in, False:
        # dial-out)
        # TODO: rename to `dial_in` and have a computed property for `dial_out`
        self.inbound = inbound
        self._subscribers = []  # : List[PeerSubscriber]

        # Uptime tracker for how long the peer has been running.
        # TODO: this should move to begin within the `_run` method (or maybe as
        # part of the `BaseService` API)
        self.start_time = datetime.datetime.now()

        # A counter of the number of messages this peer has received for each
        # message type.
        self.received_msgs = collections.defaultdict(
            int)  # : Dict[protocol.Command, int]

        # Encryption and Cryptography *stuff*
        self.egress_mac = connection.egress_mac
        self.ingress_mac = connection.ingress_mac
        # FIXME: Insecure Encryption: https://github.com/ethereum/devp2p/issues/32
        iv = b"\x00" * 16
        aes_secret = connection.aes_secret
        mac_secret = connection.mac_secret
        aes_cipher = Cipher(algorithms.AES(aes_secret), modes.CTR(iv),
                            default_backend())
        self.aes_enc = aes_cipher.encryptor()
        self.aes_dec = aes_cipher.decryptor()
        mac_cipher = Cipher(algorithms.AES(mac_secret), modes.ECB(),
                            default_backend())
        self.mac_enc = mac_cipher.encryptor().update

        # Manages the boot process
        self.boot_manager = self.get_boot_manager()

        # this port is not really used on the other side of TCP communication, py-evm had this wrong but it does not matter
        self.listen_port = listen_port
Exemplo n.º 45
0
 def __init__(self, key, iv):
     ciph = Cipher(algorithms.AES(key), modes.CBC(iv), default_backend())
     self.decrypt = ciph.decryptor().update
Exemplo n.º 46
0
def decrypt(private_key, args):

    printHeadDecrypt()

    backend = default_backend()
    key = None
    if os.path.isfile(private_key):
        with open(private_key, "rb") as key_file:
            private_key = serialization.load_pem_private_key(
                key_file.read(), password=None, backend=default_backend())

    if len(args) < 1 or len(args) > 2:
        print("""  > Number of args incorect, exit decryption proccess\n""")
        sys.exit(0)

    medfile = str(args[0])

    try:
        output = str(args[1])
        if not os.path.isdir(output):
            output = '.'
    except IndexError:
        output = '.'

    if (os.path.isfile(medfile)):
        print('  Reading file ' + medfile)
        print('  Output result in ' + output + '\n')

        print("""  Start decryption:\n""")
        fh = open(medfile, 'rb')
        try:
            b = fh.read()

            for_signature = b[:-256]
            signature = b[-256:]

            print("""  - Check signature...""")
            public_key = private_key.public_key()
            verifier = public_key.verifier(
                signature,
                cryptography.hazmat.primitives.asymmetric.padding.PSS(
                    mgf=cryptography.hazmat.primitives.asymmetric.padding.MGF1(
                        hashes.SHA256()),
                    salt_length=cryptography.hazmat.primitives.asymmetric.
                    padding.PSS.MAX_LENGTH), hashes.SHA256())
            verifier.update(for_signature)
            try:
                verifier.verify()
            except cryptography.exceptions.InvalidSignature:
                error_then_quit()

            iv = for_signature[:16]
            encrypted_key = for_signature[16:272]
            ciphertext = for_signature[272:]

            print("""  - Retreive key...""")
            try:
                key = private_key.decrypt(
                    encrypted_key,
                    cryptography.hazmat.primitives.asymmetric.padding.OAEP(
                        mgf=cryptography.hazmat.primitives.asymmetric.padding.
                        MGF1(algorithm=hashes.SHA1()),
                        algorithm=hashes.SHA1(),
                        label=None))
            except:
                error_then_quit()

            print("""  - Decrypt file(s)...""")
            try:
                cipher = Cipher(algorithms.AES(key),
                                modes.CBC(iv),
                                backend=backend)
                decryptor = cipher.decryptor()
                padded_plaintext = decryptor.update(
                    ciphertext) + decryptor.finalize()

                unpadder = padding.PKCS7(128).unpadder()
                plaintext = unpadder.update(padded_plaintext)
                plaintext += unpadder.finalize()
            except:
                error_then_quit()

            print("""  - Saving file...\n""")
            if os.path.isfile(ZIP_FILENAME):
                print('  ' + ZIP_FILENAME + ' already exist!')
                print('  Removing file ' + ZIP_FILENAME)
                os.remove(ZIP_FILENAME)

            with open(ZIP_FILENAME, 'wb') as f:
                f.write(plaintext)
                f.close()

            with zipfile.ZipFile(ZIP_FILENAME) as medzip:
                if medzip.testzip() == None:
                    medzip.extractall(output)
                medzip.close()

            print("""\n  Removing temp files...\n""")
            os.remove(ZIP_FILENAME)
            print('   * ' + ZIP_FILENAME + ' removed')

        finally:
            fh.close()

    else:
        print("""  > File not exist, exit decryption proccess\n""")
        sys.exit(0)

    print("""
   ----------------------------------------
  | Medivac decryption finish with success |
   ----------------------------------------
  """)
Exemplo n.º 47
0
def aes_ecb_dec(key, data):
    backend = default_backend()
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
    decryptor = cipher.decryptor()
    return decryptor.update(data) + decryptor.finalize()
Exemplo n.º 48
0
class AESCryptography:
    """
    This class is responsible for handling all AES cryptography operations.
    It is used to both encrypt and decrypt payloads.
    The AES 256 key and IV must be stored in environment variables:
    LMS_AES_256_KEY, LMS_AES_256_IV
    """
    def __init__(self):
        secret = self.get_secret_from_env()
        self.__key = secret[0]
        self.__iv = secret[1]
        self.cypher = Cipher(
            algorithms.AES(self.__key),
            modes.CBC(self.__iv),
            backend=default_backend()
        )
        self.pad = PKCS7(256)

    @staticmethod
    def get_secret_from_env():
        """
        Retrieves the AES 256 key and IV from environment variables:
        LMS_AES_256_KEY, LMS_AES_256_IV

        :return: tuple containing the key and IV
        :rtype: tuple
        """
        env_key = os.environ["LMS_AES_256_KEY"]
        env_iv = os.environ["LMS_AES_256_IV"]
        return (bytes.fromhex(env_key), bytes.fromhex(env_iv))

    def encrypt(self, message):
        """
        Encrypts the message using the key and IV

        :param message: the message to encrypt
        :type message: str
        :return: the encrypted cyphertext
        :rtype: byte
        """
        encryptor = self.cypher.encryptor()
        padder = self.pad.padder()
        # message to bytes
        encoded_message = bytes(message, encoding="utf-8")
        # pad message to fit block size
        padded_message = padder.update(encoded_message) + padder.finalize()
        # encrypt message
        cyphertext = encryptor.update(padded_message) + encryptor.finalize()
        return cyphertext

    def decrypt(self, cyphertext):
        """
        Decrypts the cyphertext using the key and IV

        :param cyphertext: the cyphertext to decrypt
        :type cyphertext: byte
        :return: the decrypted plaintext
        :rtype: str
        """
        decryptor = self.cypher.decryptor()
        unpadder = self.pad.unpadder()
        # decrypt cyphertext
        plaintext = decryptor.update(cyphertext) + decryptor.finalize()
        # remove padding
        plaintext = unpadder.update(plaintext) + unpadder.finalize()
        return str(plaintext, encoding="utf-8")
Exemplo n.º 49
0
class QA_TTSBroker(QA_Broker):
    def __init__(self,
                 endpoint="http://127.0.0.1:10092/api",
                 encoding="utf-8",
                 enc_key=None,
                 enc_iv=None):
        super().__init__()
        self.name = BROKER_TYPE.TTS
        self.order_handler = QA_OrderHandler()
        self._endpoint = endpoint
        self._encoding = "utf-8"
        if enc_key == None or enc_iv == None:
            self._transport_enc = False
            self._transport_enc_key = None
            self._transport_enc_iv = None
            self._cipher = None
        else:
            self._transport_enc = True
            self._transport_enc_key = enc_key
            self._transport_enc_iv = enc_iv
            backend = default_backend()
            self._cipher = Cipher(algorithms.AES(enc_key),
                                  modes.CBC(enc_iv),
                                  backend=backend)

        self._session = requests.Session()
        self.client_id = 0
        self.gddm_sh = 0  #上海股东代码
        self.gddm_sz = 0  #深圳股东代码

        self.fetcher = {
            (MARKET_TYPE.STOCK_CN, FREQUENCE.DAY): QA_fetch_get_stock_day,
            (MARKET_TYPE.STOCK_CN, FREQUENCE.FIFTEEN_MIN):
            QA_fetch_get_stock_min,
            (MARKET_TYPE.STOCK_CN, FREQUENCE.ONE_MIN): QA_fetch_get_stock_min,
            (MARKET_TYPE.STOCK_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_stock_min,
            (MARKET_TYPE.STOCK_CN, FREQUENCE.THIRTY_MIN):
            QA_fetch_get_stock_min,
            (MARKET_TYPE.STOCK_CN, FREQUENCE.SIXTY_MIN):
            QA_fetch_get_stock_min,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.DAY): QA_fetch_get_index_day,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.FIFTEEN_MIN):
            QA_fetch_get_index_min,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.ONE_MIN): QA_fetch_get_index_min,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_index_min,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.THIRTY_MIN):
            QA_fetch_get_index_min,
            (MARKET_TYPE.INDEX_CN, FREQUENCE.SIXTY_MIN):
            QA_fetch_get_index_min,
            (MARKET_TYPE.FUND_CN, FREQUENCE.DAY): QA_fetch_get_index_day,
            (MARKET_TYPE.FUND_CN, FREQUENCE.FIFTEEN_MIN):
            QA_fetch_get_index_min,
            (MARKET_TYPE.FUND_CN, FREQUENCE.ONE_MIN): QA_fetch_get_index_min,
            (MARKET_TYPE.FUND_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_index_min,
            (MARKET_TYPE.FUND_CN, FREQUENCE.THIRTY_MIN):
            QA_fetch_get_index_min,
            (MARKET_TYPE.FUND_CN, FREQUENCE.SIXTY_MIN): QA_fetch_get_index_min
        }

    def call(self, func, params=None):

        json_obj = {"func": func}

        if params is not None:
            json_obj["params"] = params

        if self._transport_enc:
            data_to_send = self.encrypt(json_obj)
            response = self._session.post(self._endpoint, data=data_to_send)
        else:
            response = self._session.post(self._endpoint, json=json_obj)
        response.encoding = self._encoding
        text = response.text

        if self._transport_enc:
            decoded_text = self.decrypt(text)
            print(decoded_text)
            return json.loads(decoded_text)
        else:
            return json.loads(text)

    def encrypt(self, source_obj):
        encrypter = self._cipher.encryptor()
        source = json.dumps(source_obj)
        source = source.encode(self._encoding)
        need_to_padding = 16 - (len(source) % 16)
        if need_to_padding > 0:
            source = source + b'\x00' * need_to_padding
        enc_data = encrypter.update(source) + encrypter.finalize()
        b64_enc_data = base64.encodebytes(enc_data)
        return urllib.parse.quote(b64_enc_data)

    def decrypt(self, source):
        decrypter = self._cipher.decryptor()
        source = urllib.parse.unquote(source)
        source = base64.decodebytes(source.encode("utf-8"))
        data_bytes = decrypter.update(source) + decrypter.finalize()
        return data_bytes.rstrip(b"\x00").decode(self._encoding)

    def data_to_df(self, result):
        if 'data' in result:
            data = result['data']
            df = pd.DataFrame(data=data)
            df.rename(columns=lambda x: cn_en_compare[x]
                      if x in cn_en_compare else x,
                      inplace=True)
            if hasattr(df, 'towards'):
                df.towards = df.towards.apply(lambda x: trade_towards_cn_en[
                    x] if x in trade_towards_cn_en else x)
            if hasattr(df, 'status'):
                df.status = df.status.apply(lambda x: order_status_cn_en[x]
                                            if x in order_status_cn_en else x)
            if hasattr(df, 'order_time'):
                df.order_time = df.order_time.apply(lambda x: '{} {}'.format(
                    datetime.date.today().strftime('%Y-%m-%d'),
                    datetime.datetime.strptime(x, '%H%M%S').strftime('%H:%M:%S'
                                                                     )))
            if hasattr(df, 'trade_time'):
                df.trade_time = df.trade_time.apply(lambda x: '{} {}'.format(
                    datetime.date.today().strftime('%Y-%m-%d'),
                    datetime.datetime.strptime(x, '%H%M%S').strftime('%H:%M:%S'
                                                                     )))
            return df
        else:
            return pd.DataFrame()

    #------ functions

    def ping(self):

        return self.call("ping", {})

    def logon(self, ip, port, version, yyb_id, account_cookie, trade_account,
              jy_passwrod, tx_password):
        data = self.call(
            "logon", {
                "ip": ip,
                "port": port,
                "version": version,
                "yyb_id": yyb_id,
                "account_no": account_cookie,
                "trade_account": trade_account,
                "jy_password": jy_passwrod,
                "tx_password": tx_password
            })
        if data['success']:
            self.client_id = data["data"]["client_id"]
            self.gddm_sh = self.query_data(5)['data'][0]['股东代码']
            self.gddm_sz = self.query_data(5)['data'][1]['股东代码']
            print('上海股东代码:%s,深圳股东代码:%s', self.gddm_sh, self.gddm_sz)
        return data

    def logoff(self):
        return self.call("logoff", {"client_id": self.client_id})

    def query_data(self, category):
        return self.call("query_data", {
            "client_id": self.client_id,
            "category": category
        })

    def send_order(self, code, price, amount, towards, order_model, market):
        """下单

        Arguments:
            code {[type]} -- [description]
            price {[type]} -- [description]
            amount {[type]} -- [description]
            towards {[type]} -- [description]
            order_model {[type]} -- [description]
            market:市场,SZ 深交所,SH 上交所

        Returns:
            [type] -- [description]
        """

        towards = 0 if towards == ORDER_DIRECTION.BUY else 1
        if order_model == ORDER_MODEL.MARKET:
            order_model = 4
        elif order_model == ORDER_MODEL.LIMIT:
            order_model = 0

        return self.call(
            "send_order", {
                'client_id':
                self.client_id,
                'category':
                towards,
                'price_type':
                order_model,
                'gddm':
                self.gddm_sh
                if market == 'SH' or market == 'sh' else self.gddm_sz,
                'zqdm':
                code,
                'price':
                price,
                'quantity':
                amount
            })

    def cancel_order(self, exchange_id, order_id):
        """

        Arguments:
            exchange_id {[type]} -- 交易所  0 深圳 1上海 (偶尔2是深圳)
            order_id {[type]} -- [description]

        Returns:
            [type] -- [description]
        """

        return self.call(
            "cancel_order", {
                'client_id': self.client_id,
                'exchange_id': exchange_id,
                'hth': order_id
            })

    def get_quote(self, code):
        return self.call("get_quote", {
            'client_id': self.client_id,
            'code': code,
        })

    def repay(self, amount):
        return self.call("repay", {
            'client_id': self.client_id,
            'amount': amount
        })

    def receive_order(self, event):

        return self.send_order(event.client_id, event.category,
                               event.price_type, event.gddm, event.zqdm,
                               event.price, event.quantity)
        #client_id, category, price_type, gddm, zqdm, price, quantity

    def run(self, event):
        if event.event_type is MARKET_EVENT.QUERY_DATA:
            self.order_handler.run(event)
            try:
                data = self.fetcher[(event.market_type,
                                     event.frequence)](code=event.code,
                                                       start=event.start,
                                                       end=event.end).values[0]
                if 'vol' in data.keys() and 'volume' not in data.keys():
                    data['volume'] = data['vol']
                elif 'vol' not in data.keys() and 'volume' in data.keys():
                    data['vol'] = data['volume']
                return data
            except Exception as e:
                QA_util_log_info('MARKET_ENGING ERROR: {}'.format(e))
                return None
        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            self.order_handler.run(event)
        elif event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            self.order_handler.run(event)
        elif event.event_type is BROKER_EVENT.TRADE:
            event = self.order_handler.run(event)
            event.message = 'trade'
            if event.callback:
                event.callback(event)

    def get_market(self, order):
        try:
            data = self.fetcher[(order.market_type, order.frequence)](
                code=order.code, start=order.datetime,
                end=order.datetime).values[0]
            if 'vol' in data.keys() and 'volume' not in data.keys():
                data['volume'] = data['vol']
            elif 'vol' not in data.keys() and 'volume' in data.keys():
                data['vol'] = data['volume']
            return data
        except Exception as e:
            QA_util_log_info('MARKET_ENGING ERROR: {}'.format(e))
            return None

    def query_orders(self, account_cookie, status='filled'):
        df = self.data_to_df(self.query_data(3 if status is 'filled' else 2))
        df['account_cookie'] = account_cookie
        if status is 'filled':
            df = df[self.dealstatus_headers] if len(df) > 0 else pd.DataFrame(
                columns=self.dealstatus_headers)
        else:
            df['cancel_amount'] = 0
            df = df[self.orderstatus_headers] if len(df) > 0 else pd.DataFrame(
                columns=self.orderstatus_headers)
        return df.set_index(['account_cookie', 'realorder_id']).sort_index()

    def query_positions(self, account_cookie):
        data = {
            'cash_available': 0.00,
            'hold_available': {},
        }
        try:
            result = self.query_data(0)
            if 'data' in result and len(result['data']) > 0:
                # 使用减法避免因为账户日内现金理财导致可用金额错误
                data['cash_available'] = round(
                    float(result['data'][0]['总资产']) -
                    float(result['data'][0]['最新市值']) -
                    float(result['data'][0]['冻结资金']), 2)

            result = self.data_to_df(self.query_data(1))
            if len(result) > 0:
                result.index = result.code
                data['hold_available'] = result[['amount']]
            return data
        except:
            return data
Exemplo n.º 50
0
# https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

test_key = bytes.fromhex('00112233445566778899AABBCCDDEEFF')



aesCipher = Cipher(algorithms.AES(test_key), modes.ECB(), backend=default_backend())

aesEnc = aesCipher.encryptor()
aesDec = aesCipher.decryptor()

import sys

with open(sys.argv[1], 'rb') as f:
	img = f.read()
	header = img[:54]
	img = img[54:]


rem = len(img) % 16

padding = b'0' * (16 - rem)

img += padding

with open("enc_ts.bmp", 'wb') as f:
	f.write(header + aesEnc.update(img))
Exemplo n.º 51
0
def decrypt(ciphertext,key):  #AES解密
    cipher = Cipher(algorithms.AES(key), modes.GCM(key), backend=default_backend())
    decryptor = cipher.decryptor()
    return decryptor.update(ciphertext)
Exemplo n.º 52
0
class BaseClient:
    C2_PUBLIC_KEY_DER = b"0h\x02a\x00\xe6}|\xb2|R\xb249\x95\x11\xa4\xfb\x11\xdd\xe8" \
        b"\xa3\x03'\xcf\x8f|\xfa\xb9.\xf9\x7fh\xa0\x99\x81V\xd9\xa5\xa05\xc1H"    \
        b"\xce\xc0\x18BW\x8a\xcc='\x94!G:\x8e\xd9\x7f\xcf\xf8\xc1\x8d\x94[@\x89"  \
        b"\xe1\xd2D\x1eq?<ys\xea\xe3d\xde\x9cc\x9b\xba8x \xf2\x88\x96\xf3\x7f"    \
        b"\xe94\x038\xe5\xd2\xaex\x15\x02\x03\x01\x00\x01"

    SESSION_KEY_SIZE = 16

    def __init__(self, session_key=None):
        if session_key:
            assert len(session_key) == self.SESSION_KEY_SIZE
        self.c2_public_key = load_der_public_key(self.C2_PUBLIC_KEY_DER)
        self.session_key = session_key or os.urandom(self.SESSION_KEY_SIZE)
        self.session_key_algorithm = AES(self.session_key)
        self.session_key_cipher = Cipher(self.session_key_algorithm, CBC(b'\0' * (self.session_key_algorithm.block_size // 8)))
        self.session_key_padding = PKCS7(self.session_key_algorithm.block_size)
        self.digest_algorithm = SHA1()

    #
    # Request
    #

    def serialize_request_payload(self, request_paylod):
        raise NotImplementedError

    def compress_request_payload(self, serialized_request_payload):
        # dummy compression
        decompressed = memoryview(serialized_request_payload)
        compressed = bytearray()
        while len(decompressed) > 0:
            size = min(len(decompressed), 0x20)
            compressed += struct.pack('<B%ds' % size, size - 1, bytes(decompressed[:size]))
            decompressed = decompressed[size:]
        compressed_request_payload = bytes(compressed)
        return compressed_request_payload

    def serialize_request(self, request_flags, compressed_request_payload):
        serialized_request = struct.pack(
            '<II%ds' % len(compressed_request_payload),
            request_flags,
            len(compressed_request_payload),
            compressed_request_payload,
        )
        return serialized_request

    def encrypt_request(self, serialized_request):
        padder = self.session_key_padding.padder()
        serialized_request_padded = padder.update(serialized_request) + padder.finalize()
        encryptor = self.session_key_cipher.encryptor()
        serialized_request_ciphertext = encryptor.update(serialized_request_padded) + encryptor.finalize()
        hasher = Hash(self.digest_algorithm)
        hasher.update(serialized_request)
        serialized_request_digest = hasher.finalize()
        session_key_ciphertext = self.c2_public_key.encrypt(
            self.session_key,
            OAEP(MGF1(self.digest_algorithm), self.digest_algorithm, None),
        )
        session_key_ciphertext_size = self.c2_public_key.key_size // 8
        serialized_request_digest_size = self.digest_algorithm.digest_size
        serialized_request_ciphertext_size = len(serialized_request_ciphertext)
        encrypted_request = struct.pack(
            '<%ds%ds%ds' % (
                session_key_ciphertext_size,
                serialized_request_digest_size,
                serialized_request_ciphertext_size
            ),
            session_key_ciphertext,
            serialized_request_digest,
            serialized_request_ciphertext,
        )
        return encrypted_request

    #
    # Response
    #

    def decrypt_response(self, encrypted_response):
        compressed_response_signature_size = self.c2_public_key.key_size // 8
        compressed_response_digest_size = self.digest_algorithm.digest_size  # unused
        compressed_response_ciphertext_size = len(encrypted_response) - compressed_response_signature_size - compressed_response_digest_size
        compressed_response_signature, compressed_response_ciphertext = struct.unpack(
            '<%ds%dx%ds' % (
                compressed_response_signature_size,
                compressed_response_digest_size,
                compressed_response_ciphertext_size,
            ),
            encrypted_response
        )
        compressed_response_signature = bytes(reversed(compressed_response_signature))
        decryptor = self.session_key_cipher.decryptor()
        compressed_response_padded = decryptor.update(compressed_response_ciphertext) + decryptor.finalize()
        unpadder = self.session_key_padding.unpadder()
        compressed_response = unpadder.update(compressed_response_padded) + unpadder.finalize()
        self.c2_public_key.verify(compressed_response_signature, compressed_response, PKCS1v15(), self.digest_algorithm)
        return compressed_response

    def decompress_response(self, compressed_response):
        compressed = memoryview(compressed_response[4:])
        decompressed = bytearray()
        while len(compressed) != 0:
            size = struct.unpack('<B', compressed[:1])[0]
            compressed = compressed[1:]
            if size < 0x20:
                size += 1
                src = compressed
                src_offset = 0
                compressed = compressed[size:]
            else:
                src_offset_hi = size & 0x1f
                size >>= 5
                if size == 7:
                    size += struct.unpack('<B', compressed[:1])[0]
                    compressed = compressed[1:]
                size += 2
                src = decompressed
                src_offset_lo = struct.unpack('<B', compressed[:1])[0]
                src_offset = -((src_offset_hi << 8) + src_offset_lo + 1)
                if len(src) < -src_offset:
                    raise Exception('len(src) < -src_offset')
                src_offset -= size
                compressed = compressed[1:]
            decompressed += bytearray(size)
            for i in range(size):
                decompressed[-size + i] = src[src_offset + i]
        serialized_response = bytes(decompressed)
        serialized_response_size = struct.unpack('<I', compressed_response[:4])[0]
        if serialized_response_size != len(serialized_response):
            raise Exception('serialized_response_size != len(serialized_response)')
        return serialized_response

    def deserialize_response(self, serialized_response):
        tmp = memoryview(serialized_response)
        serialized_response_payload_size = struct.unpack('<I', tmp[:4])[0]
        tmp = tmp[4:]
        serialized_response_payload = struct.unpack('<%ds' % serialized_response_payload_size, tmp[:serialized_response_payload_size])[0]
        tmp = tmp[serialized_response_payload_size:]
        response_flags = struct.unpack('<I', tmp[:4])[0]
        tmp = tmp[4:]  # len(tmp) > 0
        return serialized_response_payload, response_flags

    def deserialize_response_payload(self, serialized_response_payload):
        raise NotImplementedError

    #
    # Communication
    #

    def prepare_http_request(self, host, port, encrypted_request, path=None, user_agent=None, boundary=None, field_name=None, file_name=None):
        if not path:
            path_segment_count = random.randint(1, 6)
            path = ''
            for i in range(path_segment_count):
                path_segment_length = random.randint(4, 19)
                path += ''.join(random.choices(string.ascii_letters + string.digits, k=path_segment_length)) + '/'
        if not user_agent:
            user_agent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)'
        if not boundary:
            hyphen_count = random.randint(8, 23)
            alnum_count = random.randint(8, 23)
            boundary = '%s%s' % ('-' * hyphen_count, ''.join(random.choices(string.ascii_letters + string.digits, k=alnum_count)))
        if not field_name:
            field_name_length = random.randint(4, 19)
            field_name = ''.join(random.choices(string.ascii_lowercase, k=field_name_length))
        if not file_name:
            file_name_length = random.randint(4, 19)
            file_name = ''.join(random.choices(string.ascii_lowercase, k=file_name_length))
        url = 'http://%s:%d/%s' % (host, port, path)
        fields = {field_name: (file_name, encrypted_request, 'application/octet-stream')}
        multipart_encoder = requests_toolbelt.MultipartEncoder(fields=fields, boundary=boundary)
        data = multipart_encoder.to_string()
        data = data.rstrip(b'\r\n') + b'\0' * (len(encrypted_request) + 0x1000 - multipart_encoder.len)  # strip last \r\n, pad with null bytes (length must be len(payload) + 0x1000)
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate',
            'DNT': '1',
            'Connection': 'keep-alive',
            'Referer': '%s/' % host,
            'Upgrade-Insecure-Requests': '1',
            'Content-Type': multipart_encoder.content_type,
            'User-Agent': user_agent,
            'Cache-Control': 'no-cache',
        }
        request = requests.Request('POST', url, data=data, headers=headers)
        return request.prepare()

    def communicate_with_c2(self, host, port, request_flags, request_payload, timeout=None, debug_callback=None):
        serialized_request_payload = self.serialize_request_payload(request_payload)
        compressed_request_payload = self.compress_request_payload(serialized_request_payload)
        serialized_request = self.serialize_request(request_flags, compressed_request_payload)
        encrypted_request = self.encrypt_request(serialized_request)
        #
        http_request = self.prepare_http_request(host, port, encrypted_request)
        http_response = requests.Session().send(http_request, timeout=timeout)
        if debug_callback:
            debug_callback(http_request, http_response)
        http_response.raise_for_status()
        if len(http_response.content) < 0x74:
            raise Exception('len(http_response.content) < 0x74')
        encrypted_response = http_response.content
        #
        compressed_response = self.decrypt_response(encrypted_response)
        serialized_response = self.decompress_response(compressed_response)
        serialized_response_payload, response_flags = self.deserialize_response(serialized_response)
        response_payload = self.deserialize_response_payload(serialized_response_payload)
        return response_flags, response_payload
Exemplo n.º 53
0
def aes_ctr_buff(key, ctr, data, buff):
    backend = default_backend()
    cipher = Cipher(algorithms.AES(key), modes.CTR(ctr), backend=backend)
    decryptor = cipher.decryptor()
    return decryptor.update_into(data, buff)  #+ decryptor.finalize()
Exemplo n.º 54
0
def decryptStreamGenerator(fIn, passw, bufferSize, inputLength):
    # validate bufferSize
    if bufferSize % AESBlockSize != 0:
        raise ValueError("Buffer size must be a multiple of AES block size")

    if len(passw) > maxPassLen:
        raise ValueError("Password is too long.")

    fdata = fIn.read(3)
    # check if file is in AES Crypt format (also min length check)
    if (fdata != bytes("AES", "utf8") or inputLength < 136):
        raise ValueError("File is corrupted or not an AES Crypt "
                         "(or pyAesCrypt) file.")

    # check if file is in AES Crypt format, version 2
    # (the only one compatible with pyAesCrypt)
    fdata = fIn.read(1)
    if len(fdata) != 1:
        raise ValueError("File is corrupted.")

    if fdata != b"\x02":
        raise ValueError("pyAesCrypt is only compatible with version "
                         "2 of the AES Crypt file format.")

    # skip reserved byte
    fIn.read(1)

    # skip all the extensions
    while True:
        fdata = fIn.read(2)
        if len(fdata) != 2:
            raise ValueError("File is corrupted.")
        if fdata == b"\x00\x00":
            break
        fIn.read(int.from_bytes(fdata, byteorder="big"))

    # read external iv
    iv1 = fIn.read(16)
    if len(iv1) != 16:
        raise ValueError("File is corrupted.")

    # stretch password and iv
    key = stretch(passw, iv1)

    # read encrypted main iv and key
    c_iv_key = fIn.read(48)
    if len(c_iv_key) != 48:
        raise ValueError("File is corrupted.")

    # read HMAC-SHA256 of the encrypted iv and key
    hmac1 = fIn.read(32)
    if len(hmac1) != 32:
        raise ValueError("File is corrupted.")

    # compute actual HMAC-SHA256 of the encrypted iv and key
    hmac1Act = hmac.HMAC(key, hashes.SHA256(), backend=default_backend())
    hmac1Act.update(c_iv_key)

    # HMAC check
    if hmac1 != hmac1Act.finalize():
        raise ValueError("Wrong password (or file is corrupted).")

    # instantiate AES cipher
    cipher1 = Cipher(algorithms.AES(key),
                     modes.CBC(iv1),
                     backend=default_backend())
    decryptor1 = cipher1.decryptor()

    # decrypt main iv and key
    iv_key = decryptor1.update(c_iv_key) + decryptor1.finalize()

    # get internal iv and key
    iv0 = iv_key[:16]
    intKey = iv_key[16:]

    # instantiate another AES cipher
    cipher0 = Cipher(algorithms.AES(intKey),
                     modes.CBC(iv0),
                     backend=default_backend())
    decryptor0 = cipher0.decryptor()

    # instantiate actual HMAC-SHA256 of the ciphertext
    hmac0Act = hmac.HMAC(intKey, hashes.SHA256(), backend=default_backend())

    while fIn.tell() < inputLength - 32 - 1 - bufferSize:
        # read data
        cText = fIn.read(bufferSize)
        # update HMAC
        hmac0Act.update(cText)
        # decrypt data and write it to output file
        yield decryptor0.update(cText)

    # decrypt remaining ciphertext, until last block is reached
    while fIn.tell() < inputLength - 32 - 1 - AESBlockSize:
        # read data
        cText = fIn.read(AESBlockSize)
        # update HMAC
        hmac0Act.update(cText)
        # decrypt data and write it to output file
        yield decryptor0.update(cText)

    # last block reached, remove padding if needed
    # read last block

    # this is for empty files
    if fIn.tell() != inputLength - 32 - 1:
        cText = fIn.read(AESBlockSize)
        if len(cText) < AESBlockSize:
            raise ValueError("File is corrupted.")
    else:
        cText = bytes()

    # update HMAC
    hmac0Act.update(cText)

    # read plaintext file size mod 16 lsb positions
    fs16 = fIn.read(1)
    if len(fs16) != 1:
        raise ValueError("File is corrupted.")

    # decrypt last block
    pText = decryptor0.update(cText) + decryptor0.finalize()

    # remove padding
    toremove = ((16 - fs16[0]) % 16)
    if toremove != 0:
        pText = pText[:-toremove]

    # write decrypted data to output file
    yield pText

    # read HMAC-SHA256 of the encrypted file
    hmac0 = fIn.read(32)
    if len(hmac0) != 32:
        raise ValueError("File is corrupted.")

    # HMAC check
    if hmac0 != hmac0Act.finalize():
        raise ValueError("Bad HMAC (file is corrupted).")
Exemplo n.º 55
0
class BasemiIO:
    """A simple class that implements the miIO protocol."""
    device_id = None
    delta_ts = None

    def __init__(self, host: str, token: str):
        self.addr = (host, 54321)
        self.token = bytes.fromhex(token)

        key = hashlib.md5(self.token).digest()
        iv = hashlib.md5(key + self.token).digest()
        self.cipher = Cipher(algorithms.AES(key),
                             modes.CBC(iv),
                             backend=default_backend())

    def _encrypt(self, plaintext: bytes):
        padder = padding.PKCS7(128).padder()
        padded_plaintext = padder.update(plaintext) + padder.finalize()

        encryptor = self.cipher.encryptor()
        return encryptor.update(padded_plaintext) + encryptor.finalize()

    def _decrypt(self, ciphertext: bytes):
        decryptor = self.cipher.decryptor()
        padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize()

        unpadder = padding.PKCS7(128).unpadder()
        return unpadder.update(padded_plaintext) + unpadder.finalize()

    def _pack_raw(self, method: str, params: Union[dict, list] = None):
        # latest zero unnecessary
        payload = json.dumps(
            {
                'id': random.randint(100000000, 999999999),
                'method': method,
                'params': params or []
            },
            separators=(',', ':')).encode() + b'\x00'

        data = self._encrypt(payload)

        raw = b'\x21\x31'
        raw += (32 + len(data)).to_bytes(2, 'big')  # total length
        raw += b'\x00\x00\x00\x00'  # unknow
        raw += self.device_id.to_bytes(4, 'big')
        raw += int(time.time() - self.delta_ts).to_bytes(4, 'big')

        raw += hashlib.md5(raw + self.token + data).digest()
        raw += data

        assert len(raw) < 1024, "Exceeded message size"

        return raw

    def _unpack_raw(self, raw: bytes):
        assert raw[:2] == b'\x21\x31'
        # length = int.from_bytes(raw[2:4], 'big')
        # unknown = raw[4:8]
        # device_id = int.from_bytes(raw[8:12], 'big')
        # ts = int.from_bytes(raw[12:16], 'big')
        # checksum = raw[16:32]
        return self._decrypt(raw[32:])
Exemplo n.º 56
0
class TDXBroker(QA_Broker):
    def __init__(self,
                 endpoint="http://127.0.0.1:10092/api",
                 encoding="utf-8",
                 enc_key=None,
                 enc_iv=None):

        self._endpoint = endpoint
        self._encoding = "utf-8"
        if enc_key == None or enc_iv == None:
            self._transport_enc = False
            self._transport_enc_key = None
            self._transport_enc_iv = None
            self._cipher = None
        else:
            self._transport_enc = True
            self._transport_enc_key = enc_key
            self._transport_enc_iv = enc_iv
            backend = default_backend()
            self._cipher = Cipher(algorithms.AES(enc_key),
                                  modes.CBC(enc_iv),
                                  backend=backend)

        self._session = requests.Session()

    def call(self, func, params=None):

        json_obj = {"func": func}

        if params is not None:
            json_obj["params"] = params

        if self._transport_enc:
            data_to_send = self.encrypt(json_obj)
            response = self._session.post(self._endpoint, data=data_to_send)
        else:
            response = self._session.post(self._endpoint, json=json_obj)
        response.encoding = self._encoding
        text = response.text

        if self._transport_enc:
            decoded_text = self.decrypt(text)
            log.debug(decoded_text)
            return json.loads(decoded_text)
        else:
            return json.loads(text)

    def encrypt(self, source_obj):
        encrypter = self._cipher.encryptor()
        source = json.dumps(source_obj)
        source = source.encode(self._encoding)
        need_to_padding = 16 - (len(source) % 16)
        if need_to_padding > 0:
            source = source + b'\x00' * need_to_padding
        enc_data = encrypter.update(source) + encrypter.finalize()
        b64_enc_data = base64.encodebytes(enc_data)
        return urllib.parse.quote(b64_enc_data)

    def decrypt(self, source):
        decrypter = self._cipher.decryptor()
        source = urllib.parse.unquote(source)
        source = base64.decodebytes(source.encode("utf-8"))
        data_bytes = decrypter.update(source) + decrypter.finalize()
        return data_bytes.rstrip(b"\x00").decode(self._encoding)

    def data_to_df(self, result):
        if 'data' in result:
            data = result['data']
            return pd.DataFrame(data=data)

    #------ functions

    def ping(self):

        return self.call("ping", {})

    def logon(self, ip, port, version, yyb_id, account_id, trade_account,
              jy_passwrod, tx_password):
        return self.call(
            "logon", {
                "ip": ip,
                "port": port,
                "version": version,
                "yyb_id": yyb_id,
                "account_no": account_id,
                "trade_account": trade_account,
                "jy_password": jy_passwrod,
                "tx_password": tx_password
            })

    def logoff(self, client_id):
        return self.call("logoff", {"client_id": client_id})

    def query_data(self, client_id, category):
        return self.call("query_data", {
            "client_id": client_id,
            "category": category
        })

    def send_order(self, client_id, category, price_type, gddm, zqdm, price,
                   quantity):
        return self.call(
            "send_order", {
                'client_id': client_id,
                'category': category,
                'price_type': price_type,
                'gddm': gddm,
                'zqdm': zqdm,
                'price': price,
                'quantity': quantity
            })

    def cancel_order(self, client_id, exchange_id, hth):
        return self.call("cancel_order", {
            'client_id': client_id,
            'exchange_id': exchange_id,
            'hth': hth
        })

    def get_quote(self, client_id, code):
        return self.call("get_quote", {
            'client_id': client_id,
            'code': code,
        })

    def repay(self, client_id, amount):
        return self.call("repay", {'client_id': client_id, 'amount': amount})

    def receive_order(self, event):
        """
        0 限价委托; 上海限价委托 / 深圳限价委托
        1 市价委托(深圳对方最优价格)
        2 市价委托(深圳本方最优价格)    
        3 市价委托(深圳即时成交剩余撤销)
        4 市价委托(上海五档即成剩撤 / 深圳五档即成剩撤)
        5 市价委托(深圳全额成交或撤销)
        6 市价委托(上海五档即成转限价)
        """
        return self.send_order(event.client_id, event.category,
                               event.price_type, event.gddm, event.zqdm,
                               event.price, event.quantity)
        #client_id, category, price_type, gddm, zqdm, price, quantity

    def run(self, event):
        pass
Exemplo n.º 57
0
def decrypt(ciphertext, key):
    cipher = Cipher(algorithms.AES(key), mode, default_backend())
    decryptor = cipher.decryptor()

    cleartext = decryptor.update(ciphertext) + decryptor.finalize()
    return cleartext  # DO NOT DECODE
Exemplo n.º 58
0
#!/usr/bin/env  python2
# -*- coding: utf-8 -*-

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

# 0F BD D7 8E 0C 01 02 05 06 09 09 06 05 04 08 05 02 0F 38 D4 21 0D 25 15 01 36 54 20 B2 5F 15 16 D4
# 33 15 06 08 01  02 41 12 13 DE 0B 6F 21 4D 37 00 05 0B 6F 21
# 36 49 EB 20 AB C6 6A A8 62 3D D9 B3 51 7F 5C 11 50 12 0D 5F 71 35 5F 03 A6 7E D5 34 02 FF AD FC C3

backend = default_backend()
key = '\x0F\xBD\xD7\x8E\x0C\x01\x02\x05\x06\x09\x09\x06\x05\x04\x08\x05\x02\x0F\x38\xD4\x21\x0D\x25\x15\x01\x36\x54\x20\xB2\x5F\x15\x16'
iv = '\x33\x15\x06\x08\x01\x02\x41\x12\x13\xDE\x0B\x6F\x21\x4D\x37\x00\x05\x0B\x6F\x21\x4D\x37\x00\x05\x00'
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
decryptor = cipher.decryptor()
ct = decryptor.update(
    b"\x36\x49\xEB\x20\xAB\xC6\x6A\xA8\x62\x3D\xD9\xB3\x51\x7F\x5C\x11\x50\x12\x0D\x5F\x71\x35\x5F\x03\xA6\x7E\xD5\x34\x02\xFF\xAD\xFC"
) + decryptor.finalize()
print ct

cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
encryptor = cipher.encryptor()
ct = encryptor.update(b"gotodomains.xyz" + "\x00" *
                      (32 - 15)) + encryptor.finalize()
EncData = ''
for i in ct:
    EncData += '%02X ' % ord(i)
print EncData
Exemplo n.º 59
0
class device:
    def __init__(self, host, mac, devtype, timeout=10, name=None, cloud=None):
        self.host = host
        self.mac = mac.encode() if isinstance(mac, str) else mac
        self.devtype = devtype if devtype is not None else 0x272a
        self.name = name
        self.cloud = cloud
        self.timeout = timeout
        self.count = random.randrange(0xffff)
        self.iv = bytearray([
            0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba,
            0x69, 0x5a, 0x2e, 0x6f, 0x58
        ])
        self.id = bytearray([0, 0, 0, 0])
        self.type = "Unknown"
        self.lock = threading.Lock()

        self.aes = None
        key = bytearray([
            0x09, 0x76, 0x28, 0x34, 0x3f, 0xe9, 0x9e, 0x23, 0x76, 0x5c, 0x15,
            0x13, 0xac, 0xcf, 0x8b, 0x02
        ])
        self.update_aes(key)

    def update_aes(self, key):
        self.aes = Cipher(algorithms.AES(key),
                          modes.CBC(self.iv),
                          backend=default_backend())

    def encrypt(self, payload):
        encryptor = self.aes.encryptor()
        return encryptor.update(payload) + encryptor.finalize()

    def decrypt(self, payload):
        decryptor = self.aes.decryptor()
        return decryptor.update(payload) + decryptor.finalize()

    def auth(self):
        payload = bytearray(0x50)
        payload[0x04] = 0x31
        payload[0x05] = 0x31
        payload[0x06] = 0x31
        payload[0x07] = 0x31
        payload[0x08] = 0x31
        payload[0x09] = 0x31
        payload[0x0a] = 0x31
        payload[0x0b] = 0x31
        payload[0x0c] = 0x31
        payload[0x0d] = 0x31
        payload[0x0e] = 0x31
        payload[0x0f] = 0x31
        payload[0x10] = 0x31
        payload[0x11] = 0x31
        payload[0x12] = 0x31
        payload[0x1e] = 0x01
        payload[0x2d] = 0x01
        payload[0x30] = ord('T')
        payload[0x31] = ord('e')
        payload[0x32] = ord('s')
        payload[0x33] = ord('t')
        payload[0x34] = ord(' ')
        payload[0x35] = ord(' ')
        payload[0x36] = ord('1')

        response = self.send_packet(0x65, payload)
        check_error(response[0x22:0x24])
        payload = self.decrypt(response[0x38:])

        key = payload[0x04:0x14]
        if len(key) % 16 != 0:
            return False

        self.id = payload[0x00:0x04]
        self.update_aes(key)

        return True

    def get_type(self):
        return self.type

    def send_packet(self, command, payload):
        self.count = (self.count + 1) & 0xffff
        packet = bytearray(0x38)
        packet[0x00] = 0x5a
        packet[0x01] = 0xa5
        packet[0x02] = 0xaa
        packet[0x03] = 0x55
        packet[0x04] = 0x5a
        packet[0x05] = 0xa5
        packet[0x06] = 0xaa
        packet[0x07] = 0x55
        packet[0x24] = self.devtype & 0xff
        packet[0x25] = self.devtype >> 8
        packet[0x26] = command
        packet[0x28] = self.count & 0xff
        packet[0x29] = self.count >> 8
        packet[0x2a] = self.mac[0]
        packet[0x2b] = self.mac[1]
        packet[0x2c] = self.mac[2]
        packet[0x2d] = self.mac[3]
        packet[0x2e] = self.mac[4]
        packet[0x2f] = self.mac[5]
        packet[0x30] = self.id[0]
        packet[0x31] = self.id[1]
        packet[0x32] = self.id[2]
        packet[0x33] = self.id[3]

        # pad the payload for AES encryption
        if payload:
            payload += bytearray((16 - len(payload)) % 16)

        checksum = 0xbeaf
        for b in payload:
            checksum = (checksum + b) & 0xffff

        packet[0x34] = checksum & 0xff
        packet[0x35] = checksum >> 8

        payload = self.encrypt(payload)
        for i in range(len(payload)):
            packet.append(payload[i])

        checksum = 0xbeaf
        for b in packet:
            checksum = (checksum + b) & 0xffff

        packet[0x20] = checksum & 0xff
        packet[0x21] = checksum >> 8

        start_time = time.time()
        with self.lock:
            cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

            while True:
                try:
                    cs.sendto(packet, self.host)
                    cs.settimeout(1)
                    response = cs.recvfrom(2048)
                    break
                except socket.timeout:
                    if (time.time() - start_time) > self.timeout:
                        cs.close()
                        raise exception(0xfffd)
            cs.close()
        return bytearray(response[0])
Exemplo n.º 60
0
class SecureTemporaryFile(object):
    file = None

    def __init__(self, filesdir):
        """
        Create the AES Key to encrypt the uploaded file and initialize the cipher
        """
        self.key = os.urandom(32)
        self.key_id = generateRandomKey(16)
        self.key_counter_nonce = os.urandom(16)
        self.cipher = Cipher(algorithms.AES(self.key),
                             modes.CTR(self.key_counter_nonce),
                             backend=crypto_backend)
        self.filepath = os.path.join(filesdir, "%s.aes" % self.key_id)
        self.enc = self.cipher.encryptor()
        self.dec = None

    def open(self, mode):
        if self.file is None:
            if mode == 'w':
                self.fd = open(self.filepath, 'ab+')
            else:
                self.fd = open(self.filepath, 'rb')
                self.dec = self.cipher.decryptor()

        return self

    def write(self, data):
        if isinstance(data, str):
            data = data.encode()

        self.fd.write(self.enc.update(data))

    def finalize_write(self):
        self.fd.write(self.enc.finalize())

    def read(self, c=None):
        if c is None:
            data = self.fd.read()
        else:
            data = self.fd.read(c)

        if data:
            return self.dec.update(data)

        return self.dec.finalize()

    def close(self):
        if self.fd is not None:
            self.fd.close()
            self.fd = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

    def __del__(self):
        self.close()

        try:
            os.remove(self.filepath)
        except:
            pass