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()
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()
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()
def test_nonexistent_cipher(self, backend): cipher = Cipher( DummyCipher(), object(), backend ) with pytest.raises(UnsupportedAlgorithm): cipher.encryptor() with pytest.raises(UnsupportedAlgorithm): cipher.decryptor()
def test_nonexistent_cipher(self, backend, mode): cipher = Cipher( DummyCipher(), mode, backend ) with pytest.raises(UnsupportedCipher): cipher.encryptor() with pytest.raises(UnsupportedCipher): cipher.decryptor()
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)
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()
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
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
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)
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)
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()
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
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)
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
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()
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()
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)
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()
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)
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)
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)
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
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
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:]
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
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]
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
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
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
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
""" 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')
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))
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
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
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
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, )
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
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
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]")
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
def __init__(self, key, iv): ciph = Cipher(algorithms.AES(key), modes.CBC(iv), default_backend()) self.decrypt = ciph.decryptor().update
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 | ---------------------------------------- """)
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()
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")
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
# 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))
def decrypt(ciphertext,key): #AES解密 cipher = Cipher(algorithms.AES(key), modes.GCM(key), backend=default_backend()) decryptor = cipher.decryptor() return decryptor.update(ciphertext)
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
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()
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).")
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:])
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
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
#!/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
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])
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