def findsharedKEY(self, peer_public): shared_key = self.private_key.exchange(ec.ECDH(), peer_public) return shared_key
def on_message(client, userdata, msg): global name global mode global asymmetric_mode global symmetric_mode global b_public_key global b_public_key_ecdh global a_shared_key global f_key global a_key global h global hmac_key print(msg.topic + " -> " + str(msg.payload.decode())) # Connection message if (msg.topic == "connection"): print("Connection message.") # Initialize some variables name = str(msg.payload.decode()).split(":")[0] mode = str(msg.payload.decode()).split(":")[1] asymmetric_mode = int(str(msg.payload.decode()).split(":")[2]) symmetric_mode = int(str(msg.payload.decode()).split(":")[3]) # Save the variables for each device names.append(name) modes.append(mode) asymmetric_modes.append(asymmetric_mode) symmetric_modes.append(symmetric_mode) # Key exchange if (asymmetric_mode == 0): client.publish(name + "/to", "param:" + str(params_pem, 'ascii')) client.publish(name + "/to", "public:" + str(a_public_key.public_numbers().y)) else: client.publish( name + "/to", "public:" + a_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo).decode()) client.subscribe(name + "/from") print("Public key sent to device.") # Show the information on web page data = { "type": "conexion_dispositivo", "payload": msg.payload.decode() } server.send_message_to_all(json.dumps(data)) # Message from a device that has already connected else: # Topic = <Device name>/from name = str(msg.topic).split("/")[0] if (msg.topic == (name + "/from")): # Receive device public key if (str(msg.payload.decode()).split(":")[0] == "public"): # If we know its old public key, we upload it try: public_keys.pop(names.index(name)) shared_keys.pop(names.index(name)) fernet_keys.pop(names.index(name)) aead_keys.pop(names.index(name)) print("Public key uploaded from device.") # If we don't know its public key, we save it except IndexError: # If the device has 'output' or nothing if (int(mode) > 0): # HMAC key will be introduced on web page data = {"type": "hmac", "name": name, "mode": mode} # If the device has just 'input' else: # HMAC key will be introduced on device hmac_key = str(os.urandom(2).hex()) data = { "type": "hmac", "name": name, "mode": mode, "hmac_key": hmac_key } # Show the correspondent information on web page server.send_message_to_all(json.dumps(data)) print("New public key from device.") # DH key exchange if (asymmetric_modes[names.index(name)] == 0): b_public_key_number = int( str(msg.payload.decode()).split(":")[1]) peer_public_numbers = dh.DHPublicNumbers( b_public_key_number, parameters.parameter_numbers()) b_public_key = peer_public_numbers.public_key( default_backend()) public_keys.insert(names.index(name), b_public_key) a_shared_key = a_private_key.exchange(b_public_key) # ECDH key exchange else: b_public_key_number = str( msg.payload.decode()).split(":")[1] b_public_key_ecdh = load_pem_public_key( b_public_key_number.encode()) a_shared_key = a_private_key_ecdh.exchange( ec.ECDH(), b_public_key_ecdh) print("Shared key calculated.") # Save the shared key shared_keys.insert(names.index(name), a_shared_key) # We fix the shared key for Fernet using HASH and save it derived_key_fernet = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data').derive(a_shared_key) key_fernet = base64.urlsafe_b64encode(derived_key_fernet) f_key = Fernet(key_fernet) fernet_keys.insert(names.index(name), f_key) # We fix the shared key for AEAD using HASH and save it derived_key_aead = HKDF( algorithm=hashes.SHA256(), length=24, salt=None, info=b'handshake data').derive(a_shared_key) key_aead = base64.urlsafe_b64encode(derived_key_aead) a_key = aead.AESGCM(key_aead) aead_keys.insert(names.index(name), a_key) # Receive HMAC from device elif (str(msg.payload.decode()).split(":")[0] == "hmac"): # Save received HMAC print("HMAC recibida del dispositivo.") h = str(msg.payload.decode()).split(":")[1] # If the device has just 'input' if (int(mode) == 0): # DH or ECDH if (asymmetric_mode == 0): h2 = hmac.new( bytes(hmac_key, 'ascii'), bytes(str(b_public_key.public_numbers().y), 'ascii'), hashlib.sha256) else: h2 = hmac.new( bytes(hmac_key, 'ascii'), b_public_key_ecdh.public_bytes( encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo), hashlib.sha256) # Compare HMAC if (hmac.compare_digest(h, h2.hexdigest())): hmacs.append(True) data = { "type": "datos_dispositivos", "name": name, "mode": mode } # Device will be added on web page if HMAC is correct server.send_message_to_all(json.dumps(data)) print("HMAC de " + name + " coincide. Añadiendo dispositivo...") else: hmacs.append(False) # Unsubscribe client.unsubscribe(name + "/from") print("HMAC de " + name + " no coincide. Dispositivo expulsado.") # Receive message from device elif (str(msg.payload.decode()).split(": ")[0] == "message"): message = str(msg.payload.decode()).split(": ")[1] # Fernet or AEAD if (symmetric_modes[names.index(name)] == 0): message = fernet_keys[names.index(name)].decrypt( message.encode()) else: message = aead_keys[names.index(name)].decrypt( b"12345678", message.encode('latin-1'), None) print("Message from " + name + ": " + message.decode()) # Show the correspondent information on web page data = { "type": "message", "name": name, "payload": message.decode() } # model data server.send_message_to_all(json.dumps(data))
def generatesharedkey(self, pem: bytes): self.sharedkey = self.__privkey.exchange(ec.ECDH(), self.pem2key(pem)) self.derivedkey = HKDF(algorithm=hashes.SHA256(), length=16, salt=None, info=b'key exchange').derive(self.sharedkey)
def process(self, packet): print("Process") if not self.shared_secret: print("shared secret not computed") received_public_key = deserializeKey(packet.pk) received_cert = x509.load_pem_x509_certificate( packet.cert, default_backend()) received_cert_key = received_cert.public_key() self.received_key = received_cert_key if packet.nonceSignature is not FIELD_NOT_SET: # Verify nonce signature try: print("Verifying nonce") self.received_key.verify( packet.nonceSignature, str(self.nonce).encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception as e: return createPacket(HandshakePacket, status=HandshakePacket.ERROR) # Generate nonce signature if self.shared_secret: self.complete = True return None if packet.signature is not FIELD_NOT_SET: try: print("verifying signature") self.received_key.verify( packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception as e: print("Not Verified?") print('There has been an error. Sending error.') return createPacket(HandshakePacket, status=HandshakePacket.ERROR) # print("Verified?") print("nonce Verified. Signing nonce ") nonceSignature = (self.signing_key).sign( str(packet.nonce).encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) self.shared_key = self.private_key.exchange(ec.ECDH(), received_public_key) self.shared_secret = True if self.received_init: self.complete = True print("client handshake completed") return self.send_success(nonceSignature) else: print("crap Server got first packet") serialized_cert_bytes = self.cert.public_bytes( serialization.Encoding.PEM) serialized_server_public_key = serializeKey(self.public_key) return self.send_key(serialized_server_public_key, serialized_cert_bytes, nonceSignature)
def generate_master_secret(public_key, private_key): shared_key = private_key.exchange(ec.ECDH(), public_key) return shared_key
def exchange_shared_key(self, pubkey): # # used in ECDHAlgorithm if isinstance(self.raw_key, EllipticCurvePrivateKeyWithSerialization): return self.raw_key.exchange(ec.ECDH(), pubkey) raise ValueError('Invalid key for exchanging shared key')
#Seek to the beginning of the session len f.seek(0x1A5 + pdh_len) session_len = int.from_bytes(f.read(4), 'big') # Read session data f.seek(0x1A5 + 4 + pdh_len) session_data = f.read(session_len) begin_chunk = 0x1A5 + 4 + pdh_len + session_len print(hex(begin_chunk)) # DH Static Unified Model - Section 2.2.2 AMD SEV API print("Deriving shared secret") shared_secret = pdh_priv.exchange(ec.ECDH(), remote_pdh) # Get session data nonce = session_data[:0x10] wrapped_tk = session_data[0x10:0x30] iv = session_data[0x30:0x40] hmac_tk = session_data[0x40:0x60] hmac_policy = session_data[0x60:0x80] print("Deriving master secret, key-encryption-key (KEK) and key-integrity-key (KIK)") master_secret = derive_secret(shared_secret,b'sev-master-secret',nonce) kek = derive_secret(master_secret,b'sev-kek',None) kik = derive_secret(master_secret,b'sev-kik',None) calc_hmac = hmac.HMAC(kik, hashes.SHA256(), backend=default_backend())
encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo).decode() count = 1 # ECDHE ecdh_data = {'pub_key': deepvault_public_key_pem_spki, 'counter': count} count += 1 auth_post = requests.post(deepapi_host + '/auth', headers=headers, data=json.dumps(ecdh_data)) deepapi_public_key = load_pem_public_key(auth_post.json()['pub_key'].encode(), default_backend()) shared_secret = deepvault_private_key.exchange(ec.ECDH(), deepapi_public_key) # challenge-response iv = secrets.token_bytes(16) salt = secrets.token_bytes(32) iterations = 150000 kdf = PBKDF2HMAC( algorithm=SHA512(), length=32, # 32 * 8 = 256 bits salt=salt, iterations=iterations, backend=default_backend())
def test_elliptic_curve_exchange_algorithm_supported(self, monkeypatch): monkeypatch.setattr(backend, "_lib", DummyLibrary()) assert not backend.elliptic_curve_exchange_algorithm_supported( ec.ECDH(), ec.SECP256R1())
def generate_dh_key(private_key, public_key): shared_key = private_key.exchange(ec.ECDH(), public_key) digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest.update(shared_key) return digest.finalize()
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.hkdf import HKDF from pwn import * p = process("challenge.py") client_sk = ec.generate_private_key(ec.SECP384R1(), default_backend()) client_pk = client_sk.public_key() client_der = client_pk.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo) res = p.recvuntil("Send your public key (hex):") server_der = res.split("\n")[1].decode("hex") server_pk = serialization.load_der_public_key(server_der, default_backend()) shared_key = client_sk.exchange(ec.ECDH(), server_pk) derived_key = HKDF(algorithm=hashes.SHA256(), length=16, salt=None, info=b"handshake data", backend=default_backend()).derive(shared_key) p.sendline(client_der.encode('hex')) res = p.recvuntil("Please, prove you know stuffs: ") msg = process(["collide.py", derived_key.encode("hex")]).recvall().split("\n")[1] p.sendline(msg) flag = p.recvall() print(flag)
def post(self, request, eid, tok, format=None): # Verify that the employee ID exists tokR = settings.REDIS_CONN.get(eid) if tokR is None: return Response(False) # TokR is not None if not isinstance(tokR, bytes): return Response(False) # TokR is a bytes buffer if tokR.decode('utf-8') == tok: request = loads(request.body) salt = b64decode(tok) EncData = b64decode(request['data']) loaded_public_key = serialization.load_pem_public_key( b64decode(request['pub']), backend=default_backend()) loaded_private_key = serialization.load_pem_private_key( b64decode(settings.REDIS_CONN.get(eid + "pvt")), # or password=None, if in plain text password=None, backend=default_backend()) shared_key = loaded_private_key.exchange(ec.ECDH(), loaded_public_key) kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=default_backend()) AESkey = kdf.derive(shared_key) DecData = self.DecAES(AESkey, EncData) DecDataJSON = loads(DecData) OTP = DecDataJSON['OTP'] if HCenterEmployee.objects.filter(EmployeeID=eid).exists(): EmpObj = HCenterEmployee.objects.get(EmployeeID=eid) # Generate a Session Token for Employee and return it # Hash a random number config.InputTemplate['uid'] = EmpObj.Data['UID'] config.InputTemplate["bio_dict"]["FMR"] = { "LEFT_THUMB": DecDataJSON["BIO"] } res = AuthInit(config.InputTemplate, OTP) if res.get('actn') == "RETRY": res = AuthInit(config.InputTemplate, OTP) if res.get('ret') == "Y": # Employee Verification complete # In redis save EID + "auth" = Txn ID of AuthInit response settings.REDIS_CONN.set(eid + "auth", res.get('txn'), 10 * 3600) # Valid for 10 hours. # Create a new token Encrypt it with the AESkey and return in response a newcreated Token # From this point on after recieving this token HealthCenter will request Sessions from Auth Channel # from Session Server tok = sha256(urandom(128)).hexdigest() settings.REDIS_CONN.set( eid + "authed", tok, 3600) # One Token is valid for One Hour. return Response(tok) else: return Response(False) return Response(False)
def process(self, msg): if (self.msg_cnt == 0): self.server_private_key = ec.generate_private_key( ec.SECP256K1(), default_backend()) self.server_public_key = self.server_private_key.public_key() new_msg = { "pubKey": self.server_public_key.public_bytes( Encoding.DER, PublicFormat.SubjectPublicKeyInfo) } msg = new_msg self.msg_cnt += 1 elif (self.msg_cnt == 1): msg = msg.decode() msg_dict = ast.literal_eval(msg) nounce = msg_dict['nounce'] key = msg_dict['key'] ciphertext = msg_dict['ct'] signature = msg_dict['sign'] pub_key = msg_dict['pub_key'] self.client_public_key = load_der_public_key( pub_key, backend=default_backend()) self.shared_key = self.server_private_key.exchange( ec.ECDH(), self.client_public_key) cip = ChaCha20Poly1305(key) try: self.client_public_key.verify(signature, ciphertext, ec.ECDSA(hashes.SHA256())) message = cip.decrypt(nounce, ciphertext, None) print('%d : %r' % (self.id, message.decode('utf-8'))) except: print("Error while decrypt") self.msg_cnt += 1 else: msg = msg.decode() msg_dict = ast.literal_eval(msg) nounce = msg_dict['nounce'] key = msg_dict['key'] ciphertext = msg_dict['ct'] signature = msg_dict['sign'] cip = ChaCha20Poly1305(key) try: self.client_public_key.verify(signature, ciphertext, ec.ECDSA(hashes.SHA256())) message = cip.decrypt(nounce, ciphertext, None) print('%d : %r' % (self.id, message.decode('utf-8'))) except: print("Error while decrypt") self.msg_cnt += 1 print('NEXT!') return msg if len(msg) > 0 else None
def compute_sharedKey(self, pubk, privk): #deserialize pubkA publicKey = load_pem_public_key(pubk, default_backend()) shared_key = privk.exchange(ec.ECDH(), publicKey) return shared_key
def create_e_share_key(self, pub_key, private_key): return private_key.exchange(ec.ECDH(), pub_key)
def process(self, packet): print("Handshake Process") if not self.shared_secret: received_public_key = deserializeKey(packet.pk) received_cert = deserializeCert(packet.cert) received_cert_key = getKeyFromCert(received_cert) self.received_key = received_cert_key if packet.nonceSignature is not FIELD_NOT_SET: # Verify nonce signature try: # print("Verifying nonce") self.received_key.verify( packet.nonceSignature, str(self.nonce).encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception as e: # print("Nonce not Verified?") # print('There has been an error. Sending error.') return createPacket(HandshakePacket, status=HandshakePacket.ERROR) # Generate nonce signature if self.shared_secret: # print("crap Server got second packet") print("server handshake completed") self.complete = True return None # print(packet.pk) if packet.signature is not FIELD_NOT_SET: try: # print("verifying signature") self.received_key.verify( packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception as e: # print("Not Verified?") # print('There has been an error. Sending error.') return createPacket(HandshakePacket, status=HandshakePacket.ERROR) for certBytes in packet.certChain: cert = deserializeCert(certBytes) print(received_cert) received_cert_address = received_cert.subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0]._value cert_address = cert.subject.get_attributes_for_oid( NameOID.COMMON_NAME)[0]._value # print("received cert", received_cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0]._value) # print("chain cert", cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0]._value) if not cert_address.startswith( "20194") and not received_cert_address.startswith( cert_address): # print("CA verification failed") return createPacket(HandshakePacket, status=HandshakePacket.ERROR) nonceSignature = (self.signing_key).sign( str(packet.nonce).encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) self.shared_key = self.private_key.exchange(ec.ECDH(), received_public_key) self.shared_secret = True if self.received_init: self.complete = True print("client handshake completed") return self.send_success(nonceSignature) else: # print("crap Server got first packet") serialized_cert_bytes = self.cert.public_bytes( serialization.Encoding.PEM) serialized_server_public_key = serializeKey(self.public_key) return self.send_key(serialized_server_public_key, serialized_cert_bytes, nonceSignature)
def decryptSalsa(message, key): message = str(message.data) #Converts the message's ciphertext to a string message = message.split("SPACE") #Splits the message by the word 'SPACE' to seperate the peer public key and ciphertext message peer_public_key = message[0] #Assigns the portion before SPACE to variable peer_public_key loaded_public_key = serialization.load_pem_public_key(peer_public_key, backend=default_backend()) #Unserialized the peer public key so that is usable for decryption ciphertext = message[1] #Assigns the portion after SPACE to variable ciphertext ros services shared_key = key.exchange(ec.ECDH(), loaded_public_key) #Generates a shared key using the local private key and the senders public key derived_key = HKDF( #Derives key to be used for decryption from shared key algorithm=hashes.SHA256(), length=32, salt=None, info=None, backend=default_backend() ).derive(shared_key) msg_nonce = ciphertext[:8] #Seperates the nonce from the ciphertext cipher_text = ciphertext[8:] #Seperates the cipher text from the nonce
def derive(): for i in range(2): digest = hashlib.sha256(private.exchange(ec.ECDH(), peer[i])).digest() shared_key.append( Cipher(algorithms.AES(digest), modes.CBC(b'0' * 16), default_backend()))
def encrypt_payload(message, client_pub_key, auth): """ This is quite a bit but for more information I wrote a blog post https://blog.vihan.org/the-push-protocol/ Brief overview is we take our private and client public key which are ECC keys on the P-256 NIST curve and we perform a diffie-hellman (ECDH) key exchange to obtain a shared secret to generate a HKDF key which is derived with various content types to obtain the encryption parameters for an AES-128-GCM cipher. :param bytes message: Binary message :param bytes client_pub_key: :param bytes auth: """ # const salt = crypto.randomBytes(16); salt = urandom(16) # const localKeysCurve = crypto.createECDH('prime256v1'); # localKeysCurve.generateKeys(); # const localPrivateKey = localKeysCurve.getPrivateKey(); local_private_key = ec.generate_private_key(ec.SECP256R1, default_backend()) # const localPublicKey = localKeysCurve.getPublicKey(); local_public_key = local_private_key.public_key() local_public_key_bytes = local_public_key.public_numbers().encode_point() # const sharedSecret = localKeysCurve.computeSecret(subscription.keys.p256dh, 'base64') shared_secret = local_private_key.exchange( ec.ECDH(), ec.EllipticCurvePublicNumbers.from_encoded_point( ec.SECP256R1(), client_pub_key).public_key(default_backend())) # const authEncBuff = new Buffer('Content-Encoding: auth\0', 'utf8'); # const prk = hkdf(subscription.keys.auth, sharedSecret, authEncBuff, 32); # salt ikm info length prk = HKDF(algorithm=hashes.SHA256(), length=32, salt=auth, info=b'Content-Encoding: auth\0', backend=default_backend()).derive(shared_secret) server_pub_key = get_public_key() # This is context which happens to be appended to end # of all the things context = b'P-256\0' + pack('!H', len(client_pub_key)) + client_pub_key +\ pack('!H', len(local_public_key_bytes)) + local_public_key_bytes # This is something that cipher needs idk im not # crypto genius nonce = HKDF(algorithm=hashes.SHA256(), length=12, salt=salt, info=b'Content-Encoding: nonce\0' + context, backend=default_backend()).derive(prk) # CEK = Content Encryption Key # this goes into AES cek = HKDF(algorithm=hashes.SHA256(), length=16, salt=salt, info=b'Content-Encoding: aesgcm\0' + context, backend=default_backend()).derive(prk) cipher = Cipher(algorithms.AES(cek), modes.GCM(nonce), default_backend()) encryptor = cipher.encryptor() payload = pack('!H', 0) + message encrypted_payload = encryptor.update( payload) + encryptor.finalize() + encryptor.tag return encrypted_payload, local_public_key_bytes, salt
def test_elliptic_curve(self): backend = MultiBackend([ DummyEllipticCurveBackend([ ec.SECT283K1 ]) ]) assert backend.elliptic_curve_supported(ec.SECT283K1()) is True assert backend.elliptic_curve_signature_algorithm_supported( ec.ECDSA(hashes.SHA256()), ec.SECT283K1() ) is True backend.generate_elliptic_curve_private_key(ec.SECT283K1()) backend.load_elliptic_curve_private_numbers( ec.EllipticCurvePrivateNumbers( 1, ec.EllipticCurvePublicNumbers( 2, 3, ec.SECT283K1() ) ) ) backend.load_elliptic_curve_public_numbers( ec.EllipticCurvePublicNumbers( 2, 3, ec.SECT283K1() ) ) assert backend.elliptic_curve_supported(ec.SECT163K1()) is False assert backend.elliptic_curve_signature_algorithm_supported( ec.ECDSA(hashes.SHA256()), ec.SECT163K1() ) is False with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE): backend.generate_elliptic_curve_private_key(ec.SECT163K1()) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE): backend.load_elliptic_curve_private_numbers( ec.EllipticCurvePrivateNumbers( 1, ec.EllipticCurvePublicNumbers( 2, 3, ec.SECT163K1() ) ) ) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE): backend.load_elliptic_curve_public_numbers( ec.EllipticCurvePublicNumbers( 2, 3, ec.SECT163K1() ) ) assert backend.elliptic_curve_exchange_algorithm_supported( ec.ECDH(), ec.SECT283K1() ) backend2 = MultiBackend([DummyEllipticCurveBackend([])]) assert not backend2.elliptic_curve_exchange_algorithm_supported( ec.ECDH(), ec.SECT163K1() ) with pytest.raises(UnsupportedAlgorithm): backend.derive_elliptic_curve_private_key(123, DummyCurve()) assert backend.derive_elliptic_curve_private_key( 123, ec.SECT283K1()) is None
sock.send(struct.pack("!i", blksz)) privkey = peer_public_key = ec.generate_private_key(ec.SECP384R1(), default_backend()) sock.send(privkey.public_key().public_bytes( serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)) servpubkeybytes = sock.recv(120) servpubkey = serialization.load_der_public_key(servpubkeybytes, default_backend()) sharedkey = privkey.exchange(ec.ECDH(), servpubkey) derived = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive(sharedkey) IV = Random.new().read(AES.block_size) aes = AES.new(derived, AES.MODE_CBC, IV) fmt = "!3s0si" buf = bytearray(blksz * AES.block_size)
def generate_derived_keys(self, source, peer_public_key, salt): shared_key = self.key_cache[source]["private_key"].exchange(ec.ECDH(), peer_public_key) self.key_cache[source]["shared_encryption_key"] = self.derive_key(b"encryption key", salt, shared_key)
def test_skip_exchange_algorithm_unsupported(backend): with pytest.raises(pytest.skip.Exception): _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), DummyCurve())
def main(): ''' uses a select loop to process user and server messages. Forwards user input to the server. ''' args = get_args() server_addr = args.ip port = args.port server = socket.socket() server.connect((server_addr, port)) msg_buffer = {} recv_len = {} msg_len = {} msg_ids = {} symmetric_keys = {} client_private_key = ec.generate_private_key(ec.SECP384R1(), backend=default_backend()) end_to_end_keys = {} sender = "" receiver = "" realMessage = "" inputs = [server, sys.stdin] outputs = [server] message_queue = queue.Queue() waiting_accept = True username = '' username_next = False while server in inputs: readable, writable, exceptional = select.select( inputs, outputs, inputs) for s in readable: ### ### Process server messages ### if s == server: # This point may iterate multiple times until the message is completely # read since LNP.recv, receives a few bytes at a time. code = LNP.recv(s, msg_buffer, recv_len, msg_len, msg_ids) # This will not happen until the message is switched to # MSG_COMPLETE when then it is read from the buffer. if code != "LOADING_MSG": code_id, msg = LNP.get_msg_from_queue( s, msg_buffer, recv_len, msg_len, msg_ids, symmetric_keys) if code_id is not None: code = code_id # print("Message ID: " + id) if code == "MSG_CMPLT": # print("As soon as we get msg complt, message is: ", msg) if username_next: print("complete") username_msg = msg username = username_msg.split(' ')[1] sys.stdout.write(username_msg + '\n') sys.stdout.write("> " + username + ": ") sys.stdout.flush() username_next = False elif msg: # If username exists, add message prompt to end of message if username != '': name = msg.split()[2] if name[0] == "b": name = name[2:(len(name) - 1)] if is_private(name): wasSent = msg.split()[1] algorithm = algorithms.ARC4( end_to_end_keys[receiver]) cipher = Cipher(algorithm, mode=None, backend=default_backend()) decryptor = cipher.decryptor() part_decrypt = msg.split()[3] if part_decrypt[0] == "b": part_decrypt = part_decrypt[2:( len(part_decrypt) - 1)] part_decrypt = part_decrypt.encode() part_decrypt = part_decrypt.decode( 'unicode-escape').encode('ISO-8859-1') decrypted_now = decryptor.update(part_decrypt) decrypted_now = str(decrypted_now) decrypted_now = decrypted_now[2:( len(decrypted_now) - 1)] msg = "> " + wasSent + " " + decrypted_now sys.stdout.write('\r' + msg + '\n') sys.stdout.write("> " + username + ": ") # If username doesnt exist, just write message else: sys.stdout.write(msg) sys.stdout.flush() # This and any other codes can be edited in protocol.py, this way # you can add new codes for new states, e.g., is this a public # key, CODE is PUBKEY and msg contains the key. elif code == "ACCEPT": waiting_accept = False sys.stdout.write(msg) sys.stdout.flush() elif code == "DH-HELLO": pub_key = client_private_key.public_key() serial_public = pub_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo) LNP.send(s, serial_public, "DH-KEY-EXCHANGE") elif code == "DH-REPLY": new_pub_key = serialization.load_pem_public_key( msg.encode(), backend=default_backend()) shared_key = client_private_key.exchange( ec.ECDH(), new_pub_key) symm_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive(shared_key) symmetric_keys[s] = symm_key elif code == "P2P-KEY-EXCHANGE": if msg[0] == "b": msg = msg[2:(len(msg) - 1)] msg = msg.replace('\\n', '\n') new_pub_key = serialization.load_pem_public_key( msg.encode(), backend=default_backend()) shared_key = client_private_key.exchange( ec.ECDH(), new_pub_key) symm_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive(shared_key) end_to_end_keys[sender] = symm_key algorithm = algorithms.ARC4(end_to_end_keys[sender]) cipher = Cipher(algorithm, mode=None, backend=default_backend()) encryptor = cipher.encryptor() part_encrypt = realMessage.split(" ", 1)[1] part_encrypt = bytes(part_encrypt, encoding='utf8') encrypted_now = encryptor.update(part_encrypt) toSend = recip sendy = bytes(toSend, encoding='utf8') LNP.send(s, f"{sendy} {encrypted_now}", None, symmetric_keys[s]) elif code == "P2P-HELLO": sender = msg receiver = username pub_key = client_private_key.public_key() serial_public = pub_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo) toSend = "@" + sender sendy = bytes(toSend, encoding='utf8') LNP.send(s, f"{sendy} {serial_public}", "P2P-KEY-EXCHANGE", symmetric_keys[s]) elif code == "P2P-REPLY": if msg[0] == "b": msg = msg[2:(len(msg) - 1)] msg = msg.replace('\\n', '\n') new_pub_key = serialization.load_pem_public_key( msg.encode(), backend=default_backend()) shared_key = client_private_key.exchange( ec.ECDH(), new_pub_key) symm_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data', backend=default_backend()).derive(shared_key) end_to_end_keys[receiver] = symm_key elif code == "USERNAME-INVALID" or code == "USERNAME-TAKEN": sys.stdout.write(msg) sys.stdout.flush() elif code == "USERNAME-ACCEPT": username_next = True elif code == "NO_MSG" or code == "EXIT": sys.stdout.write(msg + '\n') sys.stdout.flush() inputs.remove(s) if s in writable: writable.remove(s) elif code == "CERTIFICATE-EXCHANGE": try: with open(f"{msg}.cert", "rb") as f: LNP.send(s, f.read(), "CERTIFICATE-EXCHANGE", symmetric_keys[s]) except FileNotFoundError: LNP.send(s, '', "NO-CERTIFICATE", symmetric_keys[s]) sys.stdout.write( "No certificate found for that username.\n") sys.stdout.flush() ### ### Process user input ### else: msg = sys.stdin.readline() if not waiting_accept: msg = msg.rstrip() if msg: message_queue.put(msg) if not ((username == '') or (msg == "exit()")): sys.stdout.write("> " + username + ": ") sys.stdout.flush() ### ### Send messages to server ### for s in writable: try: msg = message_queue.get_nowait() except queue.Empty: msg = None # if there is a message to send if msg: # if exit message, send the exit code if msg == "exit()": outputs.remove(s) LNP.send(s, '', "EXIT", symmetric_keys[s]) # otherwise just send the messsage else: if is_private(msg): #check if already have security recip = msg.split()[0] if recip not in end_to_end_keys: #if don't have, create LNP.send(s, f"{recip} {username}", "P2P-HELLO", symmetric_keys[s]) receiver = recip[1:] sender = username pub_key = client_private_key.public_key() serial_public = pub_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat. SubjectPublicKeyInfo) recievv = bytes(recip, encoding='utf8') LNP.send(s, f"{recievv} {serial_public}", "P2P-REPLY", symmetric_keys[s]) realMessage = msg continue algorithm = algorithms.ARC4(end_to_end_keys[sender]) cipher = Cipher(algorithm, mode=None, backend=default_backend()) encryptor = cipher.encryptor() part_encrypt = msg.split()[0][1:] encrypted_now = encryptor.update(part_encrypt) message = recip + encrypted_now LNP.send(s, message, None, symmetric_keys[s]) else: LNP.send(s, msg, None, symmetric_keys[s]) for s in exceptional: print("Disconnected: Server exception") inputs.remove(s) server.close()
def gen_shared_secret(self, publickey): return self.key.exchange(ec.ECDH(), publickey)
def ECDH(slot, iface='hid', **kwargs): ATCA_SUCCESS = 0x00 # Loading cryptoauthlib(python specific) load_cryptoauthlib() # Get the target default config cfg = eval('cfg_ateccx08a_{}_default()'.format(atca_names_map.get(iface))) # Set interface parameters if kwargs is not None: for k, v in kwargs.items(): icfg = getattr(cfg.cfg, 'atca{}'.format(iface)) setattr(icfg, k, int(v, 16)) # Basic Raspberry Pi I2C check if 'i2c' == iface and (check_if_rpi() or check_if_bbb()): cfg.cfg.atcai2c.bus = 1 # Initialize the stack assert atcab_init(cfg) == ATCA_SUCCESS # Get the device type from the info command info = bytearray(4) assert atcab_info(info) == ATCA_SUCCESS dev_type = get_device_type_id(get_device_name(info)) # Check device type if dev_type in [0, 0x20]: raise ValueError('Device does not support ECDH operations') elif dev_type != cfg.devtype: cfg.dev_type = dev_type assert atcab_release() == ATCA_SUCCESS time.sleep(1) assert atcab_init(cfg) == ATCA_SUCCESS # Create a host private key host_key = ec.generate_private_key(ec.SECP256R1(), default_backend()) # Convert host's public key into ATECCx08 format host_pub = host_key.public_key().public_numbers().encode_point()[1:] # Display the host's public key print("\nHost Public Key:") print(pretty_print_hex(host_pub, indent=' ')) # Buffers for device public key and shared secret device_pub = bytearray(64) device_shared = bytearray(32) # Generate a device private key and perform the ECDH operation # This step is using the unencrypted form of the ECDH calls due to configuration details that will be specific # for the use case. See atcab_ecdh_enc and atcab_ecdh_tempkey_ioenc functions. if dev_type == get_device_type_id('ATECC508A'): assert atcab_genkey(slot, device_pub) == ATCA_SUCCESS assert atcab_ecdh(slot, host_pub, device_shared) == ATCA_SUCCESS else: assert atcab_genkey(0xFFFF, device_pub) == ATCA_SUCCESS assert atcab_ecdh_tempkey(host_pub, device_shared) == ATCA_SUCCESS # Display the device's public key print("\nDevice public key:") print(pretty_print_hex(device_pub, indent=' ')) # Convert device public key to a cryptography public key object device_pub = ec.EllipticCurvePublicNumbers.from_encoded_point(ec.SECP256R1(), b'\04' + device_pub).public_key(default_backend()) # Perform the host side ECDH computation host_shared = host_key.exchange(ec.ECDH(), device_pub) # Display the host side computed symmetric key print('\nHost Calculated Shared Secret:') print(pretty_print_hex(host_shared, indent=' ')) # Display the device side computed symmetric key print('\nDevice Calculated Shared Secret:') print(pretty_print_hex(device_shared, indent=' ')) # Compare both independently calculated print('\nComparing host and device generated secrets:') if host_shared == device_shared: print(" Success - Generated secrets match!") else: print(" Error in calculation") assert atcab_release() == ATCA_SUCCESS
def gensharedKey(self, public_key): self.shared_key.append( self.diffieHellman.exchange(ec.ECDH(), public_key))
elif isNewData: print("Received new data from", dev.addr) if __name__ == '__main__': # scanner = Scanner().withDelegate(ScanDelegate()) # devices = scanner.scan(10.0) # # for dev in devices: # print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)) # for (adtype, desc, value) in dev.getScanData(): # print(" %s = %s" % (desc, value)) private_key = ec.generate_private_key(ec.SECP256R1(), default_backend()) public_key = private_key.public_key() shared_key = private_key.exchange(ec.ECDH(), public_key) print(" shared key :", shared_key.hex()) derived_key = HKDF(algorithm=hashes.SHA256(), length=64, salt=None, info=b'mible-setup-info', backend=default_backend()).derive(shared_key) print("derived key :", derived_key.hex()) token = derived_key[0:12] bind_key = derived_key[12:28] A = derived_key[28:44] print(" token :", token.hex()) print(" bind_key :", bind_key.hex()) print(" A :", A.hex()) aesccm = AESCCM(A)
def data_received(self, data): logger.debug("CRAP: {} side received a data of size {} from {}".format(self.mode, len(data), self.transport.get_extra_info("peername"))) self.deserializer.update(data) if self.handshakeComplete: for packet in self.deserializer.nextPackets(): if isinstance(packet, DataPacket): logger.debug('CRAP: {} side received data packet. Info:\n' 'data: {}\n'.format(self.mode, packet.data)) logger.debug('CRAP: {} side decrypting data.\n'.format(self.mode)) aes_gcm = AESGCM(self.higher_transport.dec_key) decrypted_data = aes_gcm.decrypt(self.higher_transport.other_side_IV, packet.data, None) logger.debug('CRAP: {} side decrypted data is: {}\n'.format(self.mode, decrypted_data)) logger.debug( 'CRAP: {} side incrementing other_side_IV by one from {} to {}'.format(self.mode, self.higher_transport.other_side_IV, increment_large_binary( self.higher_transport.other_side_IV))) self.higher_transport.other_side_IV = increment_large_binary(self.higher_transport.other_side_IV) logger.debug('CRAP: {} sending decrypted data to higher protocol, data: {}\n'.format(self.mode, decrypted_data)) self.higherProtocol().data_received(decrypted_data) elif isinstance(packet, ErrorPacket): logger.debug('CRAP: {} side received error packet. Info:\n' 'data: {}\n'.format(self.mode, packet.message)) else: logger.debug('CRAP: {} side expected data/error got something else: ignore'.format(self.mode)) else: # handshake for packet in self.deserializer.nextPackets(): if isinstance(packet, HandshakePacket): logger.debug('CRAP: {} side received handshake packet. Info:\n' 'status: {}\n' 'pk: {}\n' 'signature: {}\n' 'cert: {}\n' 'nonce: {}\n' 'nonce_signature: {}\n' 'cert chain: {}\n'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain)) if packet.status == HandshakePacket.NOT_STARTED: try: cert = deserialize_cert(packet.cert) logger.debug('CRAP: {} side verifying certificate common_name!\n'.format(self.mode)) self.verify_common_name(cert) logger.debug('CRAP: {} side certificate common name verified!\n'.format(self.mode)) logger.debug('CRAP: {} side verifying certificate chain of trust!\n'.format(self.mode)) self.verify_chain_of_trust(cert, packet.certChain) logger.debug('CRAP: {} side chain of trust verified!\n'.format(self.mode)) logger.debug('CRAP: {} side verifying signature received from other side!\n'.format(self.mode)) verification_key = cert.public_key() self.verification_key = verification_key verification_key.verify(packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) logger.debug('CRAP: {} side signature verified!\n'.format(self.mode)) logger.debug('CRAP: {} side creating shared key\n'.format(self.mode)) self.shared_key = self.private_key.exchange(ec.ECDH(), deserialize_public(packet.pk)) logger.debug('CRAP: {} side signing the sent nonce with signature key\n'.format(self.mode)) nonce_bytes = str(packet.nonce).encode() nonce_signature = self.signing_key.sign(nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) logger.debug('CRAP: {} side creating signature\n'.format(self.mode)) signature = self.signing_key.sign(self.public_key_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) with open('team1csr_signed.cert', 'rb') as f: signer_cert_bytes = f.read() cert_chain = [signer_cert_bytes] packet = HandshakePacket(status=HandshakePacket.SUCCESS, pk=self.public_key_bytes, signature=signature, cert=self.cert_bytes, nonce=self.nonce, nonceSignature=nonce_signature, certChain=cert_chain) packet_bytes = packet.__serialize__() logger.debug('CRAP: {} side sending handshake packet. Info:\n' 'status: {}\n' 'pk: {}\n' 'signature: {}\n' 'cert: {}\n' 'nonce: {}\n' 'nonce_signature: {}\n' 'cert chain: {}'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain)) self.transport.write(packet_bytes) except: error = 'Verification failed!' logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error)) self.handle_handshake_error() packet = HandshakePacket(status=HandshakePacket.ERROR) packet_bytes = packet.__serialize__() logger.debug('CRAP: {} side sending handshake packet. Info:\n' 'status: {}\n' 'pk: {}\n' 'signature: {}\n' 'cert: {}\n' 'nonce: {}\n' 'nonce_signature: {}\n' 'cert chain: {}\n'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain)) self.transport.write(packet_bytes) self.connection_lost() elif packet.status == HandshakePacket.SUCCESS: if not_set(packet.pk, packet.nonce, packet.signature) and is_set(packet.nonceSignature): try: if is_set(packet.cert): cert = deserialize_cert(packet.cert) verification_key = cert.public_key() else: verification_key = self.verification_key logger.debug('CRAP: {} side verifying nonce signature received from other side!\n'.format(self.mode)) verification_key.verify(packet.nonceSignature, self.nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) logger.debug('CRAP: {} side nonce signature verified!\n'.format(self.mode)) self.handshakeComplete = True logger.debug( 'CRAP: {} set handshakeComplete to True'.format(self.mode)) higher_transport = CrapTransport(self.transport, mode=self.mode, protocol=self) higher_transport.assign_gcm_values() self.higher_transport = higher_transport logger.debug('Crap: {} side calling self.higherProtocol().connection_made()'.format(self.mode)) self.higherProtocol().connection_made(higher_transport) except: logger.debug( 'CRAP: {} verifying nonce failed'.format(self.mode)) self.connection_lost() elif is_set(packet.pk, packet.cert, packet.signature, packet.nonce, packet.nonceSignature): try: cert = deserialize_cert(packet.cert) logger.debug('CRAP: {} side verifying certificate common_name!\n'.format(self.mode)) self.verify_common_name(cert) logger.debug('CRAP: {} side certificate common name verified!\n'.format(self.mode)) logger.debug('CRAP: {} side verifying certificate chain of trust!\n'.format(self.mode)) self.verify_chain_of_trust(cert, packet.certChain) logger.debug('CRAP: {} side chain of trust verified!\n'.format(self.mode)) logger.debug('CRAP: {} side verifying signature received from other side!\n'.format(self.mode)) verification_key = cert.public_key() verification_key.verify(packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) logger.debug('CRAP: {} side signature verified!\n'.format(self.mode)) logger.debug('CRAP: {} side verifying nonce signature received from other side!\n'.format(self.mode)) verification_key.verify(packet.nonceSignature, self.nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) logger.debug('CRAP: {} side nonce signature verified!\n'.format(self.mode)) logger.debug('CRAP: {} side creating shared key\n'.format(self.mode)) self.shared_key = self.private_key.exchange(ec.ECDH(), deserialize_public(packet.pk)) logger.debug( 'CRAP: {} side signing the sent nonce with signature key\n'.format(self.mode)) nonce_bytes = str(packet.nonce).encode() nonce_signature = self.signing_key.sign(nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) self.handshakeComplete = True logger.debug( 'CRAP: {} set handshakeComplete to True'.format(self.mode)) packet = HandshakePacket(status=HandshakePacket.SUCCESS, nonceSignature=nonce_signature, cert=self.cert_bytes) packet_bytes = packet.__serialize__() logger.debug('CRAP: {} side sending handshake packet. Info:\n' 'status: {}\n' 'pk: {}\n' 'signature: {}\n' 'cert: {}\n' 'nonce: {}\n' 'nonce_signature: {}\n' 'cert chain: {}'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain)) self.transport.write(packet_bytes) higher_transport = CrapTransport(self.transport, mode=self.mode, protocol=self) higher_transport.assign_gcm_values() self.higher_transport = higher_transport logger.debug( 'Crap: {} side calling self.higherProtocol().connection_made()'.format(self.mode)) self.higherProtocol().connection_made(higher_transport) except: error = 'Verification failed!' logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error)) self.handle_handshake_error() packet = HandshakePacket(status=HandshakePacket.ERROR) packet_bytes = packet.__serialize__() logger.debug('CRAP: {} side sending handshake packet. Info:\n' 'status: {}\n' 'pk: {}\n' 'signature: {}\n' 'cert: {}\n' 'nonce: {}\n' 'nonce_signature: {}\n' 'cert chain: {}'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain)) self.transport.write(packet_bytes) self.connection_lost() else: error = 'handshake fields does not match!' logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error)) self.handle_handshake_error() self.connection_lost() elif packet.status == HandshakePacket.ERROR: # Error detected on the other side error = 'an error reported from the other side' logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error)) self.handle_handshake_error() self.connection_lost() else: self.handle_handshake_error() self.connection_lost() elif isinstance(packet, ErrorPacket): logger.debug('CRAP: {} side received error packet. Info:\n' 'data: {}\n'.format(self.mode, packet.message)) else: error = 'Expected handshake/error packet and got s.th else!' logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error)) self.handle_handshake_error()
def exchange_shared_key(self, pubkey): # # used in ECDHESAlgorithm private_key = self.get_private_key() if private_key: return private_key.exchange(ec.ECDH(), pubkey) raise ValueError('Invalid key for exchanging shared key')