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 step1(self, msg): p, g, ga = msg.msg["p"], msg.msg["g"], msg.msg["ga"] self.fake_bob_dhkey = dhke.DHKey(p, g) self.fake_bob_dhkey.compute_shared(ga) data = {"gb": self.fake_bob_dhkey.ga} data = cert.create_signed_dict(data, MAN_PRI, FAKE_B_CERT) msg = router_lib.Message("B", "A", data) return msg, 2
def step0(self): # Initialise the first message to Bob. self.fake_alice_dhkey = dhke.DHKey() p = self.fake_alice_dhkey.p g = self.fake_alice_dhkey.g ga = self.fake_alice_dhkey.ga data = {"p": p, "g": g, "ga": ga} data = cert.create_signed_dict(data, MAN_PRI, FAKE_A_CERT) msg = router_lib.Message("A", "B", data) return msg
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.
isvalid = cert.validate_signed_dict(signed_data) print(isvalid) signed_data["newfield"] = 1 # Modify data isinvalid = cert.validate_signed_dict(signed_data) print(isinvalid) ### Example Inverse modulo # Given x and n, a = x^-1 mod n AKA a*x = 1 mod n x = 5 n = 3 a = cert.inverse_mod(x, n) # 2*5 mod 3 = 1 print(a) # 2 ### Example : Diffie-Hellman Key Exchange # Step 1 : A generates key a_dhkey = dhke.DHKey() print(a_dhkey.p) # p value of DHKE protocol. (prime modulus) print(a_dhkey.g) # g value of DHKE protocol. (generator) print(a_dhkey.a) # A's diffie-Hellman 'private' key, a (randomised value) 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)