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 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 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 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)
# The DataSource will want to be able to be verified by Bob, so it leaves # its Public Key somewhere. data_source_public_key = bytes(data_source.stamp) # It can save the MessageKit somewhere (IPFS, etc) and then it too can # choose to disappear (although it may also opt to continue transmitting # as many messages as may be appropriate). del data_source ############### # Back to Bob # ############### # Bob needs to reconstruct the DataSource. datasource_as_understood_by_bob = DataSource.from_public_keys( policy_public_key=policy.public_key, datasource_public_key=data_source_public_key, label=label ) # Now Bob can retrieve the original message. He just needs the MessageKit # and the DataSource which produced it. alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(alices_pubkey_bytes_saved_for_posterity) delivered_cleartexts = BOB.retrieve(message_kit=message_kit, data_source=datasource_as_understood_by_bob, alice_verifying_key=alice_pubkey_restored_from_ancient_scroll) # We show that indeed this is the passage originally encrypted by the DataSource. assert plaintext == delivered_cleartexts[0] print("Retrieved: {}".format(delivered_cleartexts[0]))
def update_cached_decrypted_measurements_list(read_time, df_json_latest_measurements, 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 Insurer 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) df = pd.DataFrame() last_timestamp = time.time() - 5 # last 5s if (df_json_latest_measurements is not None) and (df_json_latest_measurements != ACCESS_REVOKED): df = pd.read_json(df_json_latest_measurements, convert_dates=False) if len(df) > 0: # sort readings and order by timestamp df = df.sort_values(by='timestamp') # use last timestamp last_timestamp = df['timestamp'].iloc[-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: encrypted_df_readings = pd.read_sql_query( 'SELECT Timestamp, EncryptedData ' 'FROM {} ' 'WHERE Timestamp > "{}" ' 'ORDER BY Timestamp ' 'LIMIT 30;'.format(DB_NAME, last_timestamp), db_conn) for index, row in encrypted_df_readings.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) plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) except Exception as e: print(str(e)) continue readings = plaintext['carInfo'] readings['timestamp'] = row['Timestamp'] df = df.append(readings, ignore_index=True) finally: db_conn.close() # only cache last 30 readings rows_to_remove = len(df) - 30 if rows_to_remove > 0: df = df.iloc[rows_to_remove:] return df.to_json()
# 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("patient_details.msgpack", "rb"), raw=False) ipfs_api = ipfsapi.connect('127.0.0.1', 5001) f = open("ipfs.txt", "r") Hashkey = f.read() ipfs_api.get(Hashkey) os.rename(Hashkey, 'patient_details.msgpack') data = msgpack.load(open("patient_details.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 = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=data['data_source'], label=label) # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit. for message_kit in message_kits: try: start = timer() retrieved_plaintexts = doctor.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey) end = timer() plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) # Now we can get the heart rate and the associated timestamp,
def doctor_decrypt(hash_key): globalLogPublisher.addObserver(SimpleObserver()) SEEDNODE_URL = 'localhost:11501' TEMP_DOCTOR_DIR = "{}/doctor-files".format( os.path.dirname(os.path.abspath(__file__))) shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0) from doctor_keys import get_doctor_privkeys doctor_keys = get_doctor_privkeys() bob_enc_keypair = DecryptingKeypair(private_key=doctor_keys["enc"]) bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"]) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] print("Creating the Doctor ...") doctor = Bob( 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(), ) print("Doctor = ", doctor) with open("policy-metadata.json", '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() print("The Doctor joins policy for label '{}'".format( label.decode("utf-8"))) doctor.join_policy(label, alices_sig_pubkey) ipfs_api = ipfsapi.connect() file = ipfs_api.get(hash_key) print(file) os.rename(hash_key, 'patient_details.msgpack') data = msgpack.load(open("patient_details.msgpack", "rb"), raw=False) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits']) data_source = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=data['data_source'], label=label) complete_message = [] for message_kit in message_kits: print(message_kit) try: start = timer() retrieved_plaintexts = doctor.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey) end = timer() plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) complete_message.append(plaintext) print(plaintext) #with open("details.json", "w") as write_file: # json.dump(plaintext, write_file) except Exception as e: traceback.print_exc() with open("details.json", "w") as write_file: json.dump(complete_message, write_file) return complete_message
# In this case, the plaintext is a # single passage from James Joyce's Finnegan's Wake. # The matter of whether encryption makes the passage more or less readable # is left to the reader to determine. single_passage_ciphertext, _signature = enciro.encapsulate_single_message( plaintext) data_source_public_key = bytes(enciro.stamp) del enciro ############### # Back to Bob # ############### enrico_as_understood_by_bob = Enrico.from_public_keys( policy_public_key=policy.public_key, datasource_public_key=data_source_public_key, label=label) # Now Bob can retrieve the original message. alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes( alices_pubkey_bytes_saved_for_posterity) delivered_cleartexts = BOB.retrieve( message_kit=single_passage_ciphertext, data_source=enrico_as_understood_by_bob, alice_verifying_key=alice_pubkey_restored_from_ancient_scroll) # We show that indeed this is the passage originally encrypted by Enrico. assert plaintext == delivered_cleartexts[0] print("Retrieved: {}".format(delivered_cleartexts[0]))