def handle(self): sock = router_lib.SocketWrapper(self.request) dh_key = dhke.DHKey() try: # Send 1st message A to B: p, g, ga data = {"p":dh_key.p, "g":dh_key.g, "ga":dh_key.ga} signed_data = cert.create_signed_dict(data, ALICE_PRI, ALICE_CERT) signed_json = json.dumps(signed_data, sort_keys=True) sock.send(signed_json.encode("utf-8")) # Receive 2nd message B to A: gb signed_json = sock.recv() signed_json = signed_json.decode("utf-8") signed_data = json.loads(signed_json) if "error" in signed_data: raise Exception("Received error, exiting!") bob_cert = cert.Certificate(**signed_data["cert"]) if not bob_cert.validate(CA_CERT.rsa_pub): raise Exception("Certificate attached has an invalid signature!") if not bob_cert.subject_principal == "Bob": raise Exception("Certificate attached doesn't belong to Bob!") if not cert.validate_signed_dict(signed_data): raise Exception("Signature is invalid! (Data was modified?)") dh_key.compute_shared(signed_data["gb"]) # Send 3rd message A to B: request for image #### req_id = random.randint(0,9998) if req_id >= 7258: # Never send 7258, offset numbers req_id += 1 req = "Can I please have image#{:04}".format(req_id) ciphertext_req, iv = dhke.aes256_dhke_encrypt(dh_key, req) data = {"request":ciphertext_req, "iv":iv} json_data = json.dumps(data, sort_keys=True) sock.send(json_data.encode("utf-8")) # Receive 4th message B to A: reply for image #### json_data = sock.recv() json_data = json_data.decode("utf-8") data = json.loads(json_data) if "error" in data: raise Exception("Received error, exiting!") image_reply = dhke.aes256_dhke_decrypt(dh_key, data["reply"], data["iv"]) print("{} : {}".format(req_id, image_reply), flush=True) except Exception as e: traceback.print_exc() sys.stderr.flush() error = str(e) error = json.dumps({"error":error}).encode("utf-8") sock.send(error) end = json.dumps({"end":1}).encode("utf-8") sock.send(end) time.sleep(10) # Sleep for awhile so end signal can be seen.
def step2(self, msg): # Decrypt and drop message reply = msg.msg["reply"] iv = msg.msg["iv"] plaintext = dhke.aes256_dhke_decrypt(self.fake_alice_dhkey, reply, iv) print("FLAG:") print(plaintext) return None, 3
def step2(self, msg): # Decrypt and drop message request = msg.msg["request"] iv = msg.msg["iv"] plaintext = dhke.aes256_dhke_decrypt(self.fake_bob_dhkey, request, iv) print("Request by Alice:") print(plaintext) return None, 3
def handle(self): sock = router_lib.SocketWrapper(self.request) try: # Receive 1st message A to B: p, g, ga signed_json = sock.recv() signed_json = signed_json.decode("utf-8") signed_data = json.loads(signed_json) if "error" in signed_data: raise Exception("Received error, exiting!") alice_cert = cert.Certificate(**signed_data["cert"]) if not alice_cert.validate(CA_CERT.rsa_pub): raise Exception( "Certificate attached has an invalid signature!") if not alice_cert.subject_principal == "Alice": raise Exception( "Certificate attached doesn't belong to Alice!") if not cert.validate_signed_dict(signed_data): raise Exception("Signature is invalid! (Data was modified?)") dh_key = dhke.DHKey(p=signed_data["p"], g=signed_data["g"]) dh_key.compute_shared(signed_data["ga"]) # Send 2nd message B to A: gb data = {"gb": dh_key.ga} signed_data = cert.create_signed_dict(data, BOB_PRI, BOB_CERT) signed_json = json.dumps(signed_data, sort_keys=True) sock.send(signed_json.encode("utf-8")) # Receive 3rd message A to B: request for image #### json_data = sock.recv() json_data = json_data.decode("utf-8") data = json.loads(json_data) if "error" in data: raise Exception("Received error, exiting!") req = dhke.aes256_dhke_decrypt(dh_key, data["request"], data["iv"]) req_start = "can i please have image#" if not req.lower().startswith(req_start): raise Exception("Sorry, I don't like your request. :(") req_id = req[len(req_start):] req_id = int(req_id) # Send 4th message B to A: reply for image #### if req_id != 7258: image_id = req_id % len(IMAGE_DB) image_reply = IMAGE_DB[image_id] else: image_reply = "KopiCTF{101_percent_pure_acidicbaside}" ciphertext_reply, iv = dhke.aes256_dhke_encrypt( dh_key, image_reply) data = {"reply": ciphertext_reply, "iv": iv} json_data = json.dumps(data, sort_keys=True) sock.send(json_data.encode("utf-8")) print("{} : {}".format(req_id, image_reply), flush=True) except Exception as e: traceback.print_exc() sys.stderr.flush() error = str(e) error = json.dumps({"error": error}).encode("utf-8") sock.send(error) end = json.dumps({"end": 1}).encode("utf-8") sock.send(end) time.sleep(10) # Sleep for awhile so end signal can be seen.
print(a_dhkey.ga) # g^a % p print(a_dhkey.gab) # shared key : g^ab % p = None (not computed yet) # Step 2 : B generates key from A's g, p. b_dhkey = dhke.DHKey(a_dhkey.p, a_dhkey.g) print(b_dhkey.a) # B's diffie-Hellman 'private' key, b (randomised value) # Note: The 'private' key is always referenced by attribute a. # Step 3 : B computes g^ab %p b_dhkey.compute_shared(a_dhkey.ga) print(b_dhkey.gab) # Step 4 : A computes g^ab %p a_dhkey.compute_shared(b_dhkey.ga) print(a_dhkey.gab) ### Example : Diffie-Hellman based AES256 Encryption (A to B) ciphertext, iv = dhke.aes256_dhke_encrypt( a_dhkey, "Hello! This is a test message") # A's key # send ciphertext to B here... plaintext = dhke.aes256_dhke_decrypt(b_dhkey, ciphertext, iv) # B's key print(plaintext) ### Example : Create message to send on router router = router_lib.Router() source = "A" dest = "B" data = {"field1": 123, "field2": "value"} msg = router_lib.Message(source, dest, data) router.send(msg)