def loop(self): while True: try: choice = get_choice(hint='1. encrypt\n2. decrypt\nchoice: ', options=['1', '2']) if choice == '1': secret_key = os.urandom(32) self.fernet = Fernet(base64.urlsafe_b64encode(secret_key)) encrypted_secret_key = self.my_friend_public_key.encrypt( secret_key, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) encrypted_secret_key_msg = binascii.hexlify( encrypted_secret_key).decode('utf8') plaintext = input('plaintext: ') encrypted_text = self.encrypt(plaintext.encode('utf8')) msg = binascii.hexlify(encrypted_text).decode('utf8') print('offline_encrypted:{}:{}'.format( encrypted_secret_key_msg, msg)) continue if choice == '2': ciphertext = input('ciphertext: ') if ciphertext.startswith('offline_encrypted:'): encrypted_secret_key_msg, msg = ciphertext[18:].split( ':') if is_hex_str(encrypted_secret_key_msg) and is_hex_str( msg): encrypted_secret_key = bytes.fromhex( encrypted_secret_key_msg) secret_key = self.my_private_key.decrypt( encrypted_secret_key, padding.OAEP(mgf=padding.MGF1( algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) self.fernet = Fernet( base64.urlsafe_b64encode(secret_key)) try: plaintext = self.decrypt(bytes.fromhex(msg)) print('decrypted:{}'.format( plaintext.decode('utf8'))) except Exception as e: print('[!] decrypt failed: {}'.format( e.message)) else: print('[!] incorrect hex_str') else: print('[!] unrecognized ciphertext format') except (KeyboardInterrupt, EOFError): print('loop exit') break
def loop(self): while True: try: choice = get_choice(hint='1. encrypt\n2. decrypt\nchoice: ', options=['1', '2']) if choice == '1': plaintext = input('plaintext: ') encrypted_text = self.encrypt(plaintext.encode('utf8')) msg = binascii.hexlify(encrypted_text).decode('utf8') print('encrypted:{}'.format(msg)) continue if choice == '2': ciphertext = input('ciphertext: ') if ciphertext.startswith('encrypted:') and is_hex_str( ciphertext[10:]): try: plaintext = self.decrypt( bytes.fromhex(ciphertext[10:])) print('decrypted:{}'.format( plaintext.decode('utf8'))) except Exception as e: print('[!] decrypt failed: {}'.format(e.message)) else: print('[!] unrecognized ciphertext format') continue except (KeyboardInterrupt, EOFError): print('loop exit') break
def loop(self): while True: try: msg = input('> ') if msg: encrypted_text = self.encrypt(msg.encode('utf8')) msg = binascii.hexlify(encrypted_text).decode('utf8') final_msg = 'msg:{}'.format(msg) self.send_msg(final_msg) else: received_text = self.receive_msg() received_msgs = re.findall(self.msg_re, received_text) received_msgs_num = len(received_msgs) if self.history_msgs_num < received_msgs_num: print() for i in range(self.history_msgs_num, received_msgs_num): if received_msgs[i][0] != self.sender_name and received_msgs[i][2].startswith('msg:') \ and is_hex_str(received_msgs[i][2][4:]): received_bytes = bytes.fromhex( received_msgs[i][2][4:]) try: decrypted_bytes = self.decrypt( received_bytes) print('[*] {}'.format( decrypted_bytes.decode('utf8'))) except Exception as e: print('[!] decrypt failed: {}'.format( e.message)) self.history_msgs_num = received_msgs_num except (KeyboardInterrupt, EOFError): print('loop exit') break
def prepare(self): # Generate a private key for use in the exchange. private_key = ec.generate_private_key(ec.SECP384R1(), self.backend) public_key = private_key.public_key() public_key_bytes = public_key.public_bytes( Encoding.DER, PublicFormat.SubjectPublicKeyInfo) msg = 'pk:{}'.format(binascii.hexlify(public_key_bytes).decode('utf8')) self.send_msg(msg) print('wait for peer_public_key...') while True: received_text = self.receive_msg() received_msgs = re.findall(self.msg_re, received_text) filted_msgs = [] for received_msg in received_msgs: if received_msg[0] != self.sender_name and received_msg[ 2].startswith('pk:'): filted_msgs.append(received_msg) if filted_msgs: content = filted_msgs[-1][2] if is_hex_str(content[3:]): peer_public_key_bytes = bytes.fromhex(content[3:]) peer_public_key = load_der_public_key( peer_public_key_bytes, self.backend) break else: print('[!] incorrect hex_str') time.sleep(5) shared_key = private_key.exchange(ec.ECDH(), peer_public_key) # Perform key derivation. derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=self.backend).derive(shared_key) secret_key = base64.urlsafe_b64encode(derived_key) self.fernet = Fernet(secret_key)
def prepare(self): private_key = ec.generate_private_key(ec.SECP384R1(), self.backend) public_key = private_key.public_key() public_key_bytes = public_key.public_bytes( Encoding.DER, PublicFormat.SubjectPublicKeyInfo) msg = 'peer_public_key:{}'.format( binascii.hexlify(public_key_bytes).decode('utf8')) print('Please send the following message to your friend') print(msg) peer_public_key = '' while True: peer_public_key_msg = input( 'Please input peer_public_key msg from your friend: ').strip() if peer_public_key_msg.startswith( 'peer_public_key:') and is_hex_str( peer_public_key_msg[16:]): peer_public_key_bytes = bytes.fromhex(peer_public_key_msg[16:]) peer_public_key = load_der_public_key(peer_public_key_bytes, self.backend) break else: print( '[!] peer_public_key msg must start with "peer_public_key:"' ) continue shared_key = private_key.exchange(ec.ECDH(), peer_public_key) # Perform key derivation. derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=self.backend).derive(shared_key) secret_key = base64.urlsafe_b64encode(derived_key) self.fernet = Fernet(secret_key)
def prepare(self): my_key_dir = os.path.join(base_dir, 'private') my_private_key_file_path = os.path.join(my_key_dir, 'my_pri_key') my_public_key_file_path = os.path.join(my_key_dir, 'my_pub_key') friend_keys_dir_path = os.path.join(base_dir, 'friends') if not os.path.exists(my_key_dir): os.makedirs(my_key_dir) if not os.path.exists(friend_keys_dir_path): os.makedirs(friend_keys_dir_path) if not os.path.exists(my_private_key_file_path) or not os.path.exists( my_public_key_file_path): print('private or public key does not exist!') choice = get_choice(hint='1. generate key pair\n2. exit\nchoice: ', options=['1', '2']) if choice == '1': my_private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=self.backend) private_key_password = getpass.getpass( 'input a password for private_key, default is empty: ') if private_key_password: my_private_key_bytes = my_private_key.private_bytes( serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization. BestAvailableEncryption( private_key_password.encode('utf8'))) else: my_private_key_bytes = my_private_key.private_bytes( serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) open(my_private_key_file_path, 'wb').write(my_private_key_bytes) my_public_key = my_private_key.public_key() my_public_key_bytes = my_public_key.public_bytes( serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo) open(my_public_key_file_path, 'wb').write(my_public_key_bytes) if choice == '2': exit(0) choice = get_choice( hint= '1. generate secret_key for talk\n2. decrypt encrypted secret_key from your friend\nchoice: ', options=['1', '2']) if choice == '1': secret_key = os.urandom(32) friend_key_names = os.listdir(friend_keys_dir_path) if not friend_key_names: print('there is no one friend\'s public key, exit') exit(0) hint = 'friend_key_names:\n {}\ninput a key name you want: '.format( ' \n'.join(friend_key_names)) selected_friend_key_name = get_choice(hint=hint, options=friend_key_names) my_friend_public_key_file_path = os.path.join( friend_keys_dir_path, selected_friend_key_name) my_friend_public_key_content = open(my_friend_public_key_file_path, 'rb').read() my_friend_public_key = serialization.load_der_public_key( my_friend_public_key_content, self.backend) encrypted_secret_key = my_friend_public_key.encrypt( secret_key, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) msg = 'encrypted_secret_key:{}'.format( binascii.hexlify(encrypted_secret_key).decode('utf8')) print( 'Please send the following encrypted_secret_key msg to your friend' ) print(msg) if choice == '2': my_private_key_content = open(my_private_key_file_path, 'rb').read() private_key_password = getpass.getpass( 'input the password of private_key, default is empty: ') if private_key_password: my_private_key = serialization.load_der_private_key( my_private_key_content, private_key_password.encode('utf8'), self.backend) else: my_private_key = serialization.load_der_private_key( my_private_key_content, None, self.backend) while True: encrypted_secret_key_msg = input( 'Please input encrypted_secret_key msg from your friend: ' ).strip() if encrypted_secret_key_msg.startswith( 'encrypted_secret_key:') and is_hex_str( encrypted_secret_key_msg[21:]): break else: print( '[!] encrypted_secret_key msg must start with "encrypted_secret_key:" and have correct hex_str' ) continue encrypted_secret_key_bytes = bytes.fromhex( encrypted_secret_key_msg[21:]) secret_key = my_private_key.decrypt( encrypted_secret_key_bytes, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) self.fernet = Fernet(base64.urlsafe_b64encode(secret_key))