async def download_backup(host: str, private_key: PrivateKey): session = aiohttp.ClientSession() backup_privkey = master_sk_to_backup_sk(private_key) backup_pubkey = bytes(backup_privkey.get_g1()).hex() # Get nonce nonce_request = {"pubkey": backup_pubkey} nonce_url = f"{host}/get_download_nonce" nonce_response = await post(session, nonce_url, nonce_request) nonce = nonce_response["nonce"] # Sign nonce signature = bytes( AugSchemeMPL.sign(backup_privkey, std_hash(hexstr_to_bytes(nonce)))).hex() # Request backup url get_backup_url = f"{host}/download_backup" backup_request = {"pubkey": backup_pubkey, "signature": signature} backup_response = await post(session, get_backup_url, backup_request) # Download from s3 assert backup_response["success"] is True backup_url = backup_response["url"] backup_text = await get(session, backup_url) await session.close() return backup_text
async def create_wallet_backup(self, file_path: Path): all_wallets = await self.get_all_wallet_info_entries() for wallet in all_wallets: if wallet.id == 1: all_wallets.remove(wallet) break backup_pk = master_sk_to_backup_sk(self.private_key) now = uint64(int(time.time())) wallet_backup = WalletInfoBackup(all_wallets) backup: Dict[str, Any] = {} data = wallet_backup.to_json_dict() data["version"] = __version__ data["fingerprint"] = self.private_key.get_g1().get_fingerprint() data["timestamp"] = now data["start_height"] = await self.get_start_height() key_base_64 = base64.b64encode(bytes(backup_pk)) f = Fernet(key_base_64) data_bytes = json.dumps(data).encode() encrypted = f.encrypt(data_bytes) meta_data: Dict[str, Any] = {"timestamp": now, "pubkey": bytes(backup_pk.get_g1()).hex()} meta_data_bytes = json.dumps(meta_data).encode() signature = bytes(AugSchemeMPL.sign(backup_pk, std_hash(encrypted) + std_hash(meta_data_bytes))).hex() backup["data"] = encrypted.decode() backup["meta_data"] = meta_data backup["signature"] = signature backup_file_text = json.dumps(backup) file_path.write_text(backup_file_text)
def open_backup_file(file_path, private_key): backup_file_text = file_path.read_text() backup_file_json = json.loads(backup_file_text) meta_data = backup_file_json["meta_data"] meta_data_bytes = json.dumps(meta_data).encode() sig = backup_file_json["signature"] backup_pk = master_sk_to_backup_sk(private_key) my_pubkey = backup_pk.get_g1() key_base_64 = base64.b64encode(bytes(backup_pk)) f = Fernet(key_base_64) encrypted_data = backup_file_json["data"].encode() msg = std_hash(encrypted_data) + std_hash(meta_data_bytes) signature = SignatureMPL.from_bytes(hexstr_to_bytes(sig)) pubkey = PublicKeyMPL.from_bytes(hexstr_to_bytes(meta_data["pubkey"])) sig_match_my = AugSchemeMPL.verify(my_pubkey, msg, signature) sig_match_backup = AugSchemeMPL.verify(pubkey, msg, signature) assert sig_match_my is True assert sig_match_backup is True data_bytes = f.decrypt(encrypted_data) data_text = data_bytes.decode() data_json = json.loads(data_text) unencrypted = {} unencrypted["data"] = data_json unencrypted["meta_data"] = meta_data return unencrypted