def test_enrico_web_character_control_encrypt_message( enrico_web_controller_test_client, encrypt_control_request): method_name, params = encrypt_control_request endpoint = f'/{method_name}' response = enrico_web_controller_test_client.post(endpoint, data=json.dumps(params)) assert response.status_code == 200 response_data = json.loads(response.data) assert 'message_kit' in response_data['result'] assert 'signature' in response_data['result'] # Check that it serializes correctly. UmbralMessageKit.from_bytes( b64decode(response_data['result']['message_kit'])) # Send bad data to assert error return response = enrico_web_controller_test_client.post('/encrypt_message', data=json.dumps( {'bad': 'input'})) assert response.status_code == 400 del (params['message']) response = enrico_web_controller_test_client.post('/encrypt_message', data=params) assert response.status_code == 400
def encrypt_and_sign( recipient_pubkey_enc: UmbralPublicKey, plaintext: bytes, signer: 'SignatureStamp', sign_plaintext: bool = True) -> Tuple[UmbralMessageKit, Signature]: if signer is not constants.DO_NOT_SIGN: # The caller didn't expressly tell us not to sign; we'll sign. if sign_plaintext: # Sign first, encrypt second. sig_header = constants.SIGNATURE_TO_FOLLOW signature = signer(plaintext) ciphertext, capsule = pre.encrypt( recipient_pubkey_enc, sig_header + signature + plaintext) else: # Encrypt first, sign second. sig_header = constants.SIGNATURE_IS_ON_CIPHERTEXT ciphertext, capsule = pre.encrypt(recipient_pubkey_enc, sig_header + plaintext) signature = signer(ciphertext) message_kit = UmbralMessageKit( ciphertext=ciphertext, capsule=capsule, sender_verifying_key=signer.as_umbral_pubkey(), signature=signature) else: # Don't sign. signature = sig_header = constants.NOT_SIGNED ciphertext, capsule = pre.encrypt(recipient_pubkey_enc, sig_header + plaintext) message_kit = UmbralMessageKit(ciphertext=ciphertext, capsule=capsule) return message_kit, signature
def decrypt(self, channel_reader: object) -> bytes: ''' Decrypt extsting message using ChannelReader instance :param BOB: :return: ''' policy_pubkey_restored = UmbralPublicKey.from_bytes( self.policy_pubkey_bytes) data_source_restored = Enrico.from_public_keys( {SigningPower: self.data_source_pubkey_bytes}, policy_encrypting_key=policy_pubkey_restored) channel_reader.BOB.join_policy(self.label_bytes, self.alice_pubkey_bytes) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes(self.alice_pubkey_bytes)) message_kit_object = UmbralMessageKit.from_bytes(self.kit_bytes) return channel_reader.BOB.retrieve( message_kit=message_kit_object, data_source=data_source_restored, alice_verifying_key=alices_sig_pubkey, label=self.label_bytes)
def set_policy(id_as_hex): """ REST endpoint for setting a kFrag. TODO: Instead of taking a Request, use the apistar typing system to type a payload and validate / split it. TODO: Validate that the kfrag being saved is pursuant to an approved Policy (see #121). """ policy_message_kit = UmbralMessageKit.from_bytes(request.data) alices_verifying_key = policy_message_kit.sender_verifying_key alice = _alice_class.from_public_keys(verifying_key=alices_verifying_key) try: cleartext = this_node.verify_from(alice, policy_message_kit, decrypt=True) except InvalidSignature: # TODO: Perhaps we log this? return Response(status_code=400) kfrag = KFrag.from_bytes(cleartext) if not kfrag.verify(signing_pubkey=alices_verifying_key): raise InvalidSignature("{} is invalid".format(kfrag)) with ThreadedSession(db_engine) as session: datastore.attach_kfrag_to_saved_arrangement( alice, id_as_hex, kfrag, session=session) # TODO: Sign the arrangement here. #495 return "" # TODO: Return A 200, with whatever policy metadata.
def decrypt(self, label: bytes, message_kit: bytes) -> dict: """ Character control endpoint to allow Alice to decrypt her own data. """ from nucypher.characters.lawful import Enrico policy_encrypting_key = self.character.get_policy_encrypting_key_from_label(label) # TODO #846: May raise UnknownOpenSSLError and InvalidTag. message_kit = UmbralMessageKit.from_bytes(message_kit) enrico = Enrico.from_public_keys( verifying_key=message_kit.sender_verifying_key, policy_encrypting_key=policy_encrypting_key, label=label ) plaintexts = self.character.decrypt_message_kit( message_kit=message_kit, data_source=enrico, label=label ) response = {'cleartexts': plaintexts} return response
def decrypt(self, bob, item_cid, pol, sig, lab): policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(pol)) alices_sig_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(sig)) label = lab.encode() dat = self.ipfs_gateway_api.cat(item_cid) doctor = bob doctor.join_policy(label, alices_sig_pubkey) data = msgpack.loads(dat, raw=False) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits']) data_source = Enrico.from_public_keys( {SigningPower: data['data_source']}, policy_encrypting_key=policy_pubkey ) message_kit = next(message_kits) start = timer() retrieved_plaintexts = doctor.retrieve( label=label, message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey ) end = timer() plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) heart_rate = plaintext['heart_rate'] timestamp = maya.MayaDT(plaintext['timestamp']) terminal_size = shutil.get_terminal_size().columns max_width = min(terminal_size, 120) columns = max_width - 12 - 27 scale = columns / 40 retrieval_time = "Retrieval time: {:8.2f} ms".format(1000 * (end - start)) line = heart_rate# + " " + retrieval_time return line
def set_policy(self, id_as_hex, request: http.Request): """ REST endpoint for setting a kFrag. TODO: Instead of taking a Request, use the apistar typing system to type a payload and validate / split it. TODO: Validate that the kfrag being saved is pursuant to an approved Policy (see #121). """ policy_message_kit = UmbralMessageKit.from_bytes(request.body) alice = self._alice_class.from_public_keys( {SigningPower: policy_message_kit.sender_pubkey_sig}) try: cleartext = self.verify_from(alice, policy_message_kit, decrypt=True) except self.InvalidSignature: # TODO: What do we do if the Policy isn't signed properly? pass kfrag = KFrag.from_bytes(cleartext) with ThreadedSession(self.db_engine) as session: self.datastore.attach_kfrag_to_saved_arrangement(alice, id_as_hex, kfrag, session=session) return # TODO: Return A 200, with whatever policy metadata.
def test_enrico_character_control_encrypt_message(enrico_control_test_client): request_data = { 'message': b64encode( b"The admiration I had for your work has completely evaporated!"). decode(), } response = enrico_control_test_client.post('/encrypt_message', data=json.dumps(request_data)) assert response.status_code == 200 response_data = json.loads(response.data) assert 'message_kit' in response_data['result'] assert 'signature' in response_data['result'] # Check that it serializes correctly. message_kit = UmbralMessageKit.from_bytes( b64decode(response_data['result']['message_kit'])) # Send bad data to assert error return response = enrico_control_test_client.post('/encrypt_message', data=json.dumps( {'bad': 'input'})) assert response.status_code == 400 del (request_data['message']) response = enrico_control_test_client.post('/encrypt_message', data=request_data) assert response.status_code == 400
def decrypting_msg(data, policy_pubkey, label, arjuns_sig_pubkey, mayank): data = msgpack.loads(data, raw=False) print("afterjson", data) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits']) # The mayank also needs to create a view of the Data Source from its public keys data_source = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=data['data_source'], label=label ) # NuCypher network to get a re-encrypted version of each MessageKit. for message_kit in message_kits: try: start = timer() retrieved_plaintexts = mayank.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=arjuns_sig_pubkey ) end = timer() plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) msg = plaintext['msg'] name = plaintext['name'] timestamp = maya.MayaDT(plaintext['timestamp']) return (name+": "+msg+" ("+str(timestamp)+")") except Exception as e: traceback.print_exc()
def retrieve(self, label: bytes, policy_encrypting_key: bytes, alice_verifying_key: bytes, message_kit: bytes, treasure_map: Union[bytes, str, 'TreasureMap'] = None): """ Character control endpoint for re-encrypting and decrypting policy data. """ from nucypher.characters.lawful import Enrico policy_encrypting_key = UmbralPublicKey.from_bytes( policy_encrypting_key) alice_verifying_key = UmbralPublicKey.from_bytes(alice_verifying_key) message_kit = UmbralMessageKit.from_bytes( message_kit ) # TODO #846: May raise UnknownOpenSSLError and InvalidTag. enrico = Enrico.from_public_keys( verifying_key=message_kit.sender_verifying_key, policy_encrypting_key=policy_encrypting_key, label=label) self.character.join_policy(label=label, alice_verifying_key=alice_verifying_key) plaintexts = self.character.retrieve( message_kit, enrico=enrico, alice_verifying_key=alice_verifying_key, label=label, treasure_map=treasure_map) response_data = {'cleartexts': plaintexts} return response_data
def reencrypt_segment(enc_data, policy_metadata, listener): policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_metadata["policy_pubkey"])) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_metadata["alice_sig_pubkey"])) label = policy_metadata["label"].encode() data = msgpack.loads(enc_data) message_kit = UmbralMessageKit.from_bytes((data[b'track_segment_data'])) data_source = Enrico.from_public_keys(verifying_key=data[b'data_source'], policy_encrypting_key=policy_pubkey) plaintext = None try: start = timer() retrieved_plaintexts = listener.retrieve( message_kit, label=label, enrico=data_source, alice_verifying_key=alices_sig_pubkey) end = timer() plaintext = retrieved_plaintexts[0] except Exception as e: # We just want to know what went wrong and continue the demo traceback.print_exc() return plaintext
def decrypt_data(self, data_source_public_key, data, policy_info): """ Decrypt data Args: data_source_public_key (bytes): data_source_public_key data (bytes): encrypted data policy_info (dict): dict containing policy_pubkey, alice_sig_pubkey and label keys Returns: retrieved_plaintexts (list): list of str """ policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["policy_pubkey"])) alice_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["alice_sig_pubkey"])) label = policy_info["label"].encode() self.bob.join_policy(label, alice_sig_pubkey) message_kit = UmbralMessageKit.from_bytes(data) data_source = Enrico.from_public_keys( verifying_key=data_source_public_key, policy_encrypting_key=policy_pubkey) retrieved_plaintexts = self.bob.retrieve( message_kit, label=label, enrico=data_source, alice_verifying_key=alice_sig_pubkey) retrieved_plaintexts = [ x.decode('utf-8') for x in retrieved_plaintexts ] return retrieved_plaintexts
def retrieve(self, label: bytes, policy_encrypting_key: bytes, alice_verifying_key: bytes, message_kit: bytes): """ Character control endpoint for re-encrypting and decrypting policy data. """ from nucypher.characters.lawful import Enrico policy_encrypting_key = UmbralPublicKey.from_bytes(policy_encrypting_key) alice_pubkey_sig = UmbralPublicKey.from_bytes(alice_verifying_key) message_kit = UmbralMessageKit.from_bytes(message_kit) # TODO: May raise UnknownOpenSSLError and InvalidTag. data_source = Enrico.from_public_keys({SigningPower: message_kit.sender_pubkey_sig}, policy_encrypting_key=policy_encrypting_key, label=label) self.bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig) plaintexts = self.bob.retrieve(message_kit=message_kit, data_source=data_source, alice_verifying_key=alice_pubkey_sig, label=label) response_data = {'cleartexts': plaintexts} return response_data
def set_policy(id_as_hex): """ REST endpoint for setting a kFrag. """ policy_message_kit = UmbralMessageKit.from_bytes(request.data) alices_verifying_key = policy_message_kit.sender_verifying_key alice = _alice_class.from_public_keys( verifying_key=alices_verifying_key) try: cleartext = this_node.verify_from(alice, policy_message_kit, decrypt=True) except InvalidSignature: # TODO: Perhaps we log this? Essentially 355. return Response(status_code=400) if not this_node.federated_only: # This splitter probably belongs somewhere canonical. transaction_splitter = BytestringSplitter(32) tx, kfrag_bytes = transaction_splitter(cleartext, return_remainder=True) try: # Get all of the arrangements and verify that we'll be paid. # TODO: We'd love for this part to be impossible to reduce the risk of collusion. #1274 arranged_addresses = this_node.policy_agent.fetch_arrangement_addresses_from_policy_txid( tx, timeout=this_node.synchronous_query_timeout) except TimeExhausted: # Alice didn't pay. Return response with that weird status code. this_node.suspicious_activities_witnessed['freeriders'].append( (alice, f"No transaction matching {tx}.")) return Response(status=402) this_node_has_been_arranged = this_node.checksum_address in arranged_addresses if not this_node_has_been_arranged: this_node.suspicious_activities_witnessed['freeriders'].append( (alice, f"The transaction {tx} does not list me as a Worker - it lists {arranged_addresses}." )) return Response(status=402) else: _tx = NO_BLOCKCHAIN_CONNECTION kfrag_bytes = cleartext kfrag = KFrag.from_bytes(kfrag_bytes) if not kfrag.verify(signing_pubkey=alices_verifying_key): raise InvalidSignature("{} is invalid".format(kfrag)) with datastore.describe(PolicyArrangement, id_as_hex, writeable=True) as policy_arrangement: if not policy_arrangement.alice_verifying_key == alice.stamp.as_umbral_pubkey( ): raise alice.SuspiciousActivity policy_arrangement.kfrag = kfrag # TODO: Sign the arrangement here. #495 return "" # TODO: Return A 200, with whatever policy metadata.
def decrypt_for_policy(): """ input: { "label": "", "message_kit": "", "alice_pubkey": "", "bob_privkey": "", "policy_pubkey": "", "data_source_pubkey": "" } response: { "success": "", "cleartext": "", "err_msg": "" } """ result = {'success': False, 'cleartext': None, 'err_msg': None} try: j = json.loads(request.data.decode('utf-8')) # TODO: Check if the input is valid # Parse the input values label = j['label'].encode('utf-8') message_kit = UmbralMessageKit.from_bytes( base64.urlsafe_b64decode(j['message_kit'])) alice_pubkey = UmbralPublicKey.from_bytes( j['alice_pubkey'], decoder=base64.urlsafe_b64decode) bob_privkey = UmbralPrivateKey.from_bytes( j['bob_privkey'], decoder=base64.urlsafe_b64decode) policy_pubkey = UmbralPublicKey.from_bytes( j['policy_pubkey'], decoder=base64.urlsafe_b64decode) data_source_pubkey = UmbralPublicKey.from_bytes( j['data_source_pubkey'], decoder=base64.urlsafe_b64decode) # Encrypt plaintext for policy cleartext = api.decrypt_for_policy(label, message_kit, alice_pubkey, bob_privkey, policy_pubkey, data_source_pubkey) # Format the response data result['cleartext'] = base64.urlsafe_b64encode(cleartext).decode( 'utf8') result['success'] = True except Exception as e: result['success'] = False result['err_msg'] = str(e) # Create response response = jsonify(result) return response
def decrypt_for_policy(self, label: bytes, message_kit: UmbralMessageKit, alice_pubkey: UmbralPublicKey, bob_privkey: UmbralPrivateKey, policy_pubkey: UmbralPublicKey, data_source_pubkey: UmbralPublicKey): """ Decrypt data for a Policy :param label: A label to represent the policies data :param message_kit: UmbralMessageKit :param alice_pubkey: Alice's public key :param bob_privkey: Bob's private key :param policy_pubkey: Policy's private key :param data_source_pubkey: DataSource's private key :return: The decrypted cleartext """ print('decrypt_for_policy') # Initialize Bob BOB = Bob(crypto_power_ups=[ SigningPower(keypair=SigningKeypair(bob_privkey)), EncryptingPower(keypair=EncryptingKeypair(bob_privkey)) ], known_nodes=(self.ursula, ), federated_only=True, always_be_learning=True) print('-=-=-=') print(label) print(bytes(alice_pubkey)) # Bob joins the policy so that he can receive data shared on it BOB.join_policy( label, # The label - he needs to know what data he's after. bytes(alice_pubkey ), # To verify the signature, he'll need Alice's public key. # verify_sig=True, # And yes, he usually wants to verify that signature. # He can also bootstrap himself onto the network more quickly # by providing a list of known nodes at this time. node_list=[("localhost", 3601)]) print('-=-=-=2') # Bob needs to reconstruct the DataSource. datasource_as_understood_by_bob = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=bytes(data_source_pubkey), label=label) print('-=-=-=3') # NOTE: Not sure if I am doing something wrong or if this is missing # from the serialized bytes message_kit.policy_pubkey = policy_pubkey # Now Bob can retrieve the original message. He just needs the MessageKit # and the DataSource which produced it. cleartexts = BOB.retrieve(message_kit=message_kit, data_source=datasource_as_understood_by_bob, alice_verifying_key=alice_pubkey) print('-=-=-=4') return cleartexts[0]
def get(self): "User should send Bob password to decrypt files" try: user = request.args.get("user") pw = request.args.get("password") label = request.args.get("label") frmt = request.args.get("frmt") except: response = {'message': "Insufficient Query Params"} return make_response(jsonify(response)), 404 keyringBob = NucypherKeyring(account=user) keyringBob.unlock(password=pw) bob = Bob(keyring=keyringBob, known_nodes=[ursula], federated_only=True, learn_on_same_thread=True, domain=TEMPORARY_DOMAIN) bob.join_policy(label.encode(), alice_sig_pubkey) from nucypher.characters.lawful import Enrico global globalStorage enrico1 = Enrico.from_public_keys( verifying_key=globalStorage[label]["data_source_public_key"], policy_encrypting_key=globalStorage[label]["policy_pubkey"]) imgUrl = base_uri + label + "." + frmt response = requests.get(imgUrl) ciphertext = UmbralMessageKit.from_bytes(response.content) decrypted_plaintext = bob.retrieve( ciphertext, label=label.encode(), enrico=enrico1, alice_verifying_key=alice_sig_pubkey) return send_file(io.BytesIO(decrypted_plaintext[0]), mimetype="image/" + frmt, as_attachment=False, attachment_filename='{}.'.format(label) + frmt), 200
def downloadFile(self, username, receipt, policy_info): hash = receipt['hash_key'] input = self.ipfs_gateway_api.cat(hash) enc_privkey, sig_privkey = self.reveal_private_keys(username) bob_enc_key = DecryptingKeypair(private_key=enc_privkey) bob_sig_keyp = SigningKeypair(private_key=sig_privkey) enc_power = DecryptingPower(keypair=bob_enc_key) sig_power = SigningPower(keypair=bob_sig_keyp) power_ups = [enc_power, sig_power] self.Bob = Bob( federated_only=True, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes=[self.ursula], save_metadata=False, network_middleware=RestMiddleware(), ) policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_info["policy_pubkey"])) enrico = Enrico.from_public_keys( {SigningPower: UmbralPublicKey.from_bytes(bytes.fromhex(receipt['data_source_public_key']))}, policy_encrypting_key=policy_pubkey ) alice_pubkey_restored = UmbralPublicKey.from_bytes(base58.b58decode(policy_info['alice_sig_pubkey'])) self.Bob.join_policy(policy_info['label'].encode(), alice_pubkey_restored) data = msgpack.loads(input, raw=False) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits']) message_kit = next(message_kits) retrieved_plaintexts = self.Bob.retrieve( message_kit, enrico=enrico, alice_verifying_key=alice_pubkey_restored, label=policy_info['label'].encode(), ) plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) print(plaintext) decrypted_data = plaintext['data'] return decrypted_data
def reencrypt_data(data_filepath, policy_filename, listener): ''' Now that the listener joined the policy in the NuCypher network, he can retrieve encrypted data which he can decrypt with his private key. ''' with open(policy_filename, 'r') as f: policy_data = json.load(f) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["policy_pubkey"])) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["alice_sig_pubkey"])) label = policy_data["label"].encode() track_encrypted_files = os.scandir(data_filepath) for track_segment_encrypted in track_encrypted_files: if not track_segment_encrypted.name.endswith('_encrypted'): continue with open(track_segment_encrypted, 'rb') as f: data = msgpack.load(f) message_kit = UmbralMessageKit.from_bytes(data[b'track_segment_data']) data_source = Enrico.from_public_keys( verifying_key=data[b'data_source'], policy_encrypting_key=policy_pubkey) try: start = timer() retrieved_plaintexts = listener.retrieve( message_kit, label=label, enrico=data_source, alice_verifying_key=alices_sig_pubkey) end = timer() plaintext = retrieved_plaintexts[0] file_name = track_segment_encrypted.path[:-10] + "_decrypted.mp3" with open(file_name, 'wb') as f: f.write(plaintext) except Exception as e: # We just want to know what went wrong and continue the demo traceback.print_exc()
def post(self): keys = request.json['keys'] path = self.writeKeys(keys) password = request.json['password'] address = request.json['address'] passwd = PBKDF2(password, address.encode(), 20, count=30000, hmac_hash_module=SHA256).hex() keyring = NucypherKeyring(account=address, keyring_root="./keys") keyring.unlock(password=passwd) bob = Bob(known_nodes=[self.URSULA], checksum_address=address, domain='lynx', keyring=keyring) enrico_key = request.json['enrico_key'] policy_key = request.json['policy_key'] data_source = Enrico.from_public_keys( verifying_key=bytes.fromhex(enrico_key), policy_encrypting_key=UmbralPublicKey.from_bytes( bytes.fromhex(policy_key))) ciphertext = request.json['ciphertext'] message_kit = UmbralMessageKit.from_bytes(bytes.fromhex(ciphertext)) label = request.json['label'] alice_pubkey = request.json['alice_pubkey'] alice_pubkey_umbral = UmbralPublicKey.from_bytes( bytes.fromhex(alice_pubkey)) print("Retrieving...") retrieved_plaintexts = bob.retrieve( message_kit, label=label.encode(), enrico=data_source, alice_verifying_key=alice_pubkey_umbral) print("Retrieved.") result = retrieved_plaintexts[0].decode("utf-8") self.readAndDeleteKeys(address, keyring) #delete keys return result
def get_treasure_map_from_known_ursulas(self, networky_stuff, map_id): """ Iterate through swarm, asking for the TreasureMap. Return the first one who has it. TODO: What if a node gives a bunk TreasureMap? """ from nucypher.network.protocols import dht_value_splitter for node in self.known_nodes.values(): response = networky_stuff.get_treasure_map_from_node(node, map_id) if response.status_code == 200 and response.content: # TODO: Make this prettier header, _signature_for_ursula, pubkey_sig_alice, hrac, encrypted_treasure_map = \ dht_with_hrac_splitter(response.content, return_remainder=True) tmap_messaage_kit = UmbralMessageKit.from_bytes( encrypted_treasure_map) return tmap_messaage_kit else: assert False
def test_treasure_map_stored_by_ursula_is_the_correct_one_for_bob(alice, bob, ursulas, enacted_policy): """ The TreasureMap given by Alice to Ursula is the correct one for Bob; he can decrypt and read it. """ treasure_map_as_set_on_network = ursulas[0].server.storage[ digest(enacted_policy.treasure_map_dht_key())] header, _signature_for_ursula, pubkey_sig_alice, hrac, encrypted_treasure_map = dht_with_hrac_splitter( treasure_map_as_set_on_network, return_remainder=True) assert header == constants.BYTESTRING_IS_TREASURE_MAP tmap_message_kit = UmbralMessageKit.from_bytes(encrypted_treasure_map) verified, treasure_map_as_decrypted_by_bob = bob.verify_from(alice, tmap_message_kit, decrypt=True, ) assert treasure_map_as_decrypted_by_bob == enacted_policy.treasure_map.packed_payload() assert verified is True
def retrieve(): """ Character control endpoint for re-encrypting and decrypting policy data. """ try: request_data = json.loads(request.data) label = b64decode(request_data['label']) policy_pubkey_enc = bytes.fromhex( request_data['policy_encrypting_pubkey']) alice_pubkey_sig = bytes.fromhex( request_data['alice_signing_pubkey']) datasource_pubkey_sig = bytes.fromhex( request_data['datasource_signing_pubkey']) message_kit = b64decode(request_data['message_kit']) except (KeyError, JSONDecodeError) as e: return Response(e, status=400) policy_pubkey_enc = UmbralPublicKey.from_bytes(policy_pubkey_enc) alice_pubkey_sig = UmbralPublicKey.from_bytes(alice_pubkey_sig) message_kit = UmbralMessageKit.from_bytes(message_kit) data_source = DataSource.from_public_keys(policy_pubkey_enc, datasource_pubkey_sig, label=label) drone_bob.join_policy(label=label, alice_pubkey_sig=alice_pubkey_sig) plaintexts = drone_bob.retrieve(message_kit=message_kit, data_source=data_source, alice_verifying_key=alice_pubkey_sig) plaintexts = [ b64encode(plaintext).decode() for plaintext in plaintexts ] response_data = { 'result': { 'plaintext': plaintexts, } } return Response(json.dumps(response_data), status=200)
def test_message_kit_serialization_via_enrico(enacted_federated_policy, federated_alice): # Enrico enrico = Enrico.from_alice(federated_alice, label=enacted_federated_policy.label) # Plaintext message = 'this is a message' plaintext_bytes = bytes(message, encoding='utf-8') # Create message_kit, signature = enrico.encrypt_message(plaintext=plaintext_bytes) # Serialize message_kit_bytes = message_kit.to_bytes() # Deserialize the_same_message_kit = UmbralMessageKit.from_bytes(message_kit_bytes) # Confirm assert message_kit_bytes == the_same_message_kit.to_bytes()
def set_policy(self, hrac_as_hex, request: http.Request): """ REST endpoint for setting a kFrag. TODO: Instead of taking a Request, use the apistar typing system to type a payload and validate / split it. TODO: Validate that the kfrag being saved is pursuant to an approved Policy (see #121). """ hrac = binascii.unhexlify(hrac_as_hex) policy_message_kit = UmbralMessageKit.from_bytes(request.body) # group_payload_splitter = BytestringSplitter(PublicKey) # policy_payload_splitter = BytestringSplitter((KFrag, KFRAG_LENGTH)) alice = self._alice_class.from_public_keys( {SigningPower: policy_message_kit.sender_pubkey_sig}) verified, cleartext = self.verify_from(alice, policy_message_kit, decrypt=True) if not verified: # TODO: What do we do if the Policy isn't signed properly? pass # # alices_signature, policy_payload =\ # BytestringSplitter(Signature)(cleartext, return_remainder=True) # TODO: If we're not adding anything else in the payload, stop using the # splitter here. # kfrag = policy_payload_splitter(policy_payload)[0] kfrag = KFrag.from_bytes(cleartext) with ThreadedSession(self.db_engine) as session: self.datastore.attach_kfrag_to_saved_arrangement(alice, hrac_as_hex, kfrag, session=session) return # TODO: Return A 200, with whatever policy metadata.
def decrypt(self, label: bytes, message_kit: bytes): """ Character control endpoint to allow Alice to decrypt her own data. """ from nucypher.characters.lawful import Enrico policy_encrypting_key = self.character.get_policy_pubkey_from_label( label) message_kit = UmbralMessageKit.from_bytes( message_kit ) # TODO #846: May raise UnknownOpenSSLError and InvalidTag. data_source = Enrico.from_public_keys( {SigningPower: message_kit.sender_pubkey_sig}, policy_encrypting_key=policy_encrypting_key, label=label) plaintexts = self.alice.decrypt_message_kit(message_kit=message_kit, data_source=data_source, label=label) return {'cleartexts': plaintexts}
policy_pubkey = PublicKey.from_bytes( bytes.fromhex(policy_data["policy_pubkey"])) alices_sig_pubkey = PublicKey.from_bytes( bytes.fromhex(policy_data["alice_sig_pubkey"])) label = policy_data["label"].encode() print("The Doctor joins policy for label '{}'".format(label.decode("utf-8"))) doctor.join_policy(label, alices_sig_pubkey) # Now that the Doctor joined the policy in the NuCypher network, # he can retrieve encrypted data which he can decrypt with his private key. # But first we need some encrypted data! # Let's read the file produced by the heart monitor and unpack the MessageKits, # which are the individual ciphertexts. data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits']) # The doctor also needs to create a view of the Data Source from its public keys data_source = Enrico.from_public_keys(verifying_key=data['data_source'], policy_encrypting_key=policy_pubkey) # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit. for message_kit in message_kits: start = timer() retrieved_plaintexts = doctor.retrieve( message_kit, label=label, enrico=data_source, alice_verifying_key=alices_sig_pubkey) end = timer()
def update_cached_decrypted_heartbeats_list(read_time, json_latest_values, bob_id): if int(read_time) == 0: # button never clicked but triggered by interval return None # Let's join the policy generated by Alicia. We just need some info about it. with open(POLICY_INFO_FILE, 'r') as f: policy_data = json.load(f) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data['policy_pubkey'])) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data['alice_sig_pubkey'])) label = policy_data['label'].encode() if not joined: print("The Doctor joins policy for label '{}' " "and pubkey {}".format(policy_data['label'], policy_data['policy_pubkey'])) bob.join_policy(label, alices_sig_pubkey) joined.append(label) with open(DATA_SOURCE_INFO_FILE, "rb") as file: data_source_metadata = msgpack.load(file, raw=False) cached_hb_values = collections.OrderedDict() if (json_latest_values is not None) and (json_latest_values != ACCESS_REVOKED): cached_hb_values = json.loads( json_latest_values, object_pairs_hook=collections.OrderedDict) last_timestamp = time.time() - 5 # last 5s if len(cached_hb_values) > 0: # use last timestamp last_timestamp = list(cached_hb_values.keys())[-1] # Bob also needs to create a view of the Data Source from its public keys data_source = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=data_source_metadata['data_source_pub_key'], label=label) db_conn = sqlite3.connect(DB_FILE) try: df = pd.read_sql_query( 'SELECT Timestamp, EncryptedData ' 'FROM {} ' 'WHERE Timestamp > "{}" ' 'ORDER BY Timestamp;'.format(DB_NAME, last_timestamp), db_conn) for index, row in df.iterrows(): kit_bytes = bytes.fromhex(row['EncryptedData']) message_kit = UmbralMessageKit.from_bytes(kit_bytes) # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit. try: retrieved_plaintexts = bob.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey) hb = msgpack.loads(retrieved_plaintexts[0], raw=False) except Exception as e: print(str(e)) continue timestamp = row['Timestamp'] cached_hb_values[timestamp] = hb finally: db_conn.close() # only cache last 30s while len(cached_hb_values) > 30: cached_hb_values.popitem(False) return json.dumps(cached_hb_values)
def decryptDelegated(): # Fetch Request Data # { # "bobKeys": "{\"enc\": \"40f05590a27491caf37049366fefd43e46034e4308f4f1fd233c166bc3980ab4\", \"sig\": \"3bcf21d3cb160118b499a883023569c60476f8731bd9eade11016c5030c1ca5d\"}", # "policy_public_key": "02aef01b40c0a62a9a1f650dd9a8381695e21a7b3826c748a5b64831aa0dd9862c", # "alice_sig_pubkey": "036c5d361000e6fbf3c4a84c98f924a3206e8a72c758a67e8300b5bee111b5fa97", # "label": "1stlabel", # "message": "messagekit", # "data_source": "03a38eef9fd09c9841585dea93791e139a3003d540539673c8c719af55e46c0c1b", # } json_data = json.loads(request.data.decode('utf-8')) bob_private_keys = json.loads(json_data['bobKeys']) policy_public_key = json_data['policy_public_key'] alice_signing_key = json_data['alice_sig_pubkey'] label = json_data['label'] # username = json_data['username'] message = json_data['message'] data_source = json_data['data_source'] data_source = bytes.fromhex(data_source) print (bob_private_keys['enc']) enc = UmbralPrivateKey.from_bytes(bytes.fromhex(bob_private_keys["enc"])) sig = UmbralPrivateKey.from_bytes(bytes.fromhex(bob_private_keys["sig"])) # signingPublic = sig.get_pubkey() # bobFilePath = os.path.join(os.getcwd(), 'bob/' + username + '.json') # doctor_pubkeys = _get_keys(bobFilePath, UmbralPublicKey) # print (signingPublic == doctor_pubkeys['sig']) # print (signingPublic) # print (doctor_pubkeys['sig']) print ('\n\n\n') bob_enc_keypair = DecryptingKeypair(private_key=enc) bob_sig_keypair = SigningKeypair(private_key=sig) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] doctor = Bob( domains={'TEMPORARY_DOMAIN'}, is_me=True, federated_only=True, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes={ursula}, save_metadata=False, network_middleware=RestMiddleware() ) policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_public_key)) alices_sig_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(alice_signing_key)) label = label.encode() doctor.join_policy(label, alices_sig_pubkey) message_kit = UmbralMessageKit.from_bytes(bytes.fromhex(message)) print (message_kit == MessageKit) print (message_kit) print (MessageKit) print ('\n\n\n') data_source = Enrico.from_public_keys( {SigningPower: data_source}, policy_encrypting_key=policy_pubkey ) retrieved_plaintexts = doctor.retrieve( label=label, message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey ) # the object to be sent back to front end # { # "fileFieldCount": 2, # "textFieldCount": 2, # "files (stringified)": { # "fileKey1": "fileUrl1", # "fileKey2": "fileUrl2" # }, # "textFields (stringified)": { # "age": "18", # "name": "arvind" # } # } plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) # the object from plaintext data_obj = createDataObject(plaintext, json_data['label']) return jsonify(data_obj)
def encryptData(): # { the object received in the request # "fileFieldCount": 2, # "textFieldCount": 2, # "0": "1st File", # "1": "2nd File", # "fileNames (stringified)": { # "0": "blood", # "1": "2nd File Name" # }, # "textFields (stringified)": { # "age": "18", # "name": "arvind" # } # # "username": "******", # "password": "******", # "hash": "", # "alice": "/home/arvind/Documents/ethDenver/umbral/alice/arvind/alice.config", # "label": "1stlabel" # # } json_data = request.form.to_dict() fileFieldCount= int(json_data['fileFieldCount']) # object that contains the files file_obj={} # object that contains all the other form fields form_field_obj ={} print("requetssss ------") print(request.files.to_dict()) print(request.form.to_dict()) print('json_data') print(json_data) fileNames = json.loads(json_data['fileNames']) textFields = json.loads(json_data['textFields']) for i in range(0, fileFieldCount): file_obj[fileNames[str(i)]] = request.files[str(i)].read() textFieldsKeys = list(textFields.keys()) for key in textFieldsKeys: form_field_obj[key] = textFields[key] data_obj = {} data_obj['file_obj'] = file_obj data_obj['form_field_obj'] = form_field_obj label = json_data['label'] aliceFile = json_data['alice'] password = json_data['password'] file_url = '/tmp/' + label + '.json' label = label.encode() hash = data_obj obj_to_be_stored = createDataObject(hash, json_data['label']) f = open(file_url, 'w') f.write(json.dumps(obj_to_be_stored)) f.close() alice_config = AliceConfiguration.from_configuration_file( filepath=aliceFile, known_nodes={ursula}, start_learning_now=False, ) alice_config.keyring.unlock(password=password) alicia = alice_config(domains={'TEMPORARY_DOMAIN'}) alicia.start_learning_loop(now=True) policy_pubkey = alicia.get_policy_pubkey_from_label(label) # Initialise Enrico enrico = Enrico(policy_encrypting_key=policy_pubkey) print ("Done upto 111") hash = msgpack.dumps(hash, use_bin_type=True) message_kit, _signature = enrico.encrypt_message(hash) message_kit_bytes = message_kit.to_bytes() newMsg = UmbralMessageKit.from_bytes(message_kit_bytes) print ("\n\ncheck") print (message_kit_bytes == newMsg.to_bytes()) print (message_kit) print (newMsg) data = {} data['message'] = message_kit_bytes.hex() data['label'] = label.decode('utf-8') data['policy_public_key'] = policy_pubkey.to_bytes().hex() data['alice_sig_pubkey'] = bytes(alicia.stamp).hex() data['data_source'] = bytes(enrico.stamp).hex() print ('result\n') print (data) print ('#####\n') return json.dumps(data)