def initiate_session(self):
     # Perform the initial connection handshake for agreeing on a shared secret
     ### TODO: Your code here!
     # This can be broken into code run just on the server or just on the client
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         my_public_iv, my_private_iv = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key, flag = self.recv()
         their_public_key = int(their_public_key)
         # Obtain our shared secret
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         self.shared_hash = shared_hash.encode("ascii")
         # Send them our public iv seed
         self.send(bytes(str(my_public_iv), "ascii"))
         # Receive their public iv seed
         their_public_iv, flag = self.recv()
         their_public_iv = int(their_public_iv)
         # Obtain our shared iv
         shared_iv = str(calculate_iv(their_public_iv,
                                      my_private_iv)).encode("ascii")
         print("Shared hash: \"{}\"".format(shared_hash))
         print("--------------------------------------")
         # initialize the cipher
         self.cipher = AES.new(shared_hash[:32], AES.MODE_CBC,
                               shared_iv[:16])
Example #2
0
    def test_dh(self):
        from dh import create_dh_key, calculate_dh_secret
        for _ in range(5):
            alice_pub, alice_priv = create_dh_key()
            bob_pub, bob_priv = create_dh_key()

            alice_sec = calculate_dh_secret(bob_pub, alice_priv)
            bob_sec = calculate_dh_secret(alice_pub, bob_priv)

            self.assertEqual(alice_sec, bob_sec)
Example #3
0
    def initiate_session(self):
        # Perform the initial connection handshake

        # Create our public & private key
        my_public_key, my_private_key = create_dh_key()
        # Send them our public key
        self.send(bytes(str(my_public_key), "ascii"))
        # Receive their public key
        their_public_key = int(self.recv())

        if self.server:
            # Create the initialization vector
            iv = get_random_bytes(AES.block_size)
            # Send them the initialization vector
            self.send(iv)
        elif self.client:
            # Receive the initialization vector
            iv = self.recv()

        # Convert the iv to an integer. We send the iv as a byte array, as that's
        #     how python wants things sent over a connection
        iv = int.from_bytes(iv, byteorder='big')

        # Calculate the shared secret
        self.shared_hash = calculate_dh_secret(their_public_key,
                                               my_private_key)
        print("Shared hash: {}".format(self.shared_hash.hexdigest()))

        # Create the counter object for the cipher. Crypto handles the incrementing
        ctr = Counter.new(128, initial_value=iv)

        # Create the cipher
        self.cipher = AES.new(self.shared_hash.digest(),
                              AES.MODE_CTR,
                              counter=ctr)
Example #4
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret 

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the clientasdsad
        if self.server or self.client:
            # Calculate Diffie-Hellman key pair
            my_public_key, my_private_key = create_dh_key()

            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))

            # Receive their public key
            their_public_key = int(self.recv())

            # Obtain our shared secret
            self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(self.shared_hash))
            self.shared_hash = bytes(self.shared_hash, "ascii")

        # Used AES instead of XOR for stronger encryption.
        iv = Random.new().read(AES.block_size)

        # Define the shared_hash and the cipher
        # Shared hash to be used as the key is declared as self.SH to make it reusable in other cipher
        # Used AES Mode of CBC
        self.SH                = self.shared_hash[:16]
        self.cipher            = AES.new(self.SH, AES.MODE_CBC, iv)

        # Create hmac_secret for HMAC
        # HMAC secret is taken from the shared key so the secret key is stronger
        self.hmac_secret       = self.shared_hash[17:]
Example #5
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))
        # key encryption key
        # AES-256, might change the mode
        self.cipher = AES.new(shared_hash[:32], AES.MODE_CFB,
                              shared_hash[32:48])

        #initialise a counter to prevent replay attacks
        #use the remaining bytes from the DH handshake so this value is secret
        self.counter = int(shared_hash[48:])

        #the server will generate a random key and send it via and encrypted channel
        if self.server:
            f = open("/dev/random", "rU")
            newkey = f.read(32)
            newiv = f.read(16)
            self.send(newkey)
            self.send(newiv)
        if self.client:
            newkey = self.recv()
            newiv = self.recv()
        #now build the content encryption cipher
        self.cipher = AES.new(newkey, AES.MODE_CFB, newiv)
Example #6
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.key = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(self.key))

        # Create a counter from PyCrypto library. Has 128 bits and uses a randomly generated initial value
        counter = Counter.new(128)

        # Creating AES cipher with 16 bit key, counter mode and counter initialised in previous line
        self.cipher = AES.new(self.key[:16], AES.MODE_CTR, counter=counter) # Changes from XOR to AES

        self.send_seed = read_hex(self.key[:4])
        self.recv_seed = self.send_seed
        print("Send seed: {}".format(self.send_seed))
        print("Recv seed: {}".format(self.recv_seed))
Example #7
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret 

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key, key_len=64)
            print("Shared session key: {}".format(binascii.hexlify(shared_hash)))

            # The first 256 bit from shared hash is the key of hmac
            self.hmac = HMAC.new(shared_hash[:32], digestmod=SHA256)

            # TODO: exchange iv
            # TODO: use a global bloom filter to avoid iv re-use in a reasonable time period,
            # and we can add a time stamp after iv to avoid replay if the iv filter is reset

            # The last 256 bit from shared hash is the key of hmac
            cipher_key = shared_hash[:-32]
            # TODO: init cipher with aes-cfb using cipher_key and iv
            # Default XOR algorithm can only take a key of length 32
            self.cipher = XOR.new(shared_hash[:4])
    def initiate_session(self):
        # Perform the initial connection handshake

        # Create our public & private key
        my_public_key, my_private_key = create_dh_key()
        # Send them our public key
        self.send(bytes(str(my_public_key), "ascii"))
        # Receive their public key
        their_public_key = int(self.recv())

        if self.server:
            # Create the initialization vector
            iv = get_random_bytes(AES.block_size)
            # Send them the initialization vector
            self.send(iv)
        elif self.client:
            # Receive the initialization vector
            iv = self.recv()

        # Convert the iv to an integer. We send the iv as a byte array, as that's
        #     how python wants things sent over a connection
        iv = int.from_bytes(iv, byteorder='big')

        # Calculate the shared secret
        self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)
        print("Shared hash: {}".format(self.shared_hash.hexdigest()))

        # Create the counter object for the cipher. Crypto handles the incrementing
        ctr = Counter.new(128, initial_value = iv)

        # Create the cipher
        self.cipher = AES.new(self.shared_hash.digest(), AES.MODE_CTR, counter=ctr)
Example #9
0
 def initiate_session(self):
     '''
     Perform the initial connection handshake for agreeing on a shared secret.
     This can be broken into code run just on the server or just on the client.
     All the function want to do here is to ensure the data confidentiality.
     Key: A key used to generate IV. Obtained from shuffled shared hash.
     '''
     if self.server or self.client:
         # DH crete keys
         my_public_key, my_private_key = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key = int(self.recv())
         # Obtain our shared secret
         self.shared_hash = calculate_dh_secret(their_public_key,
                                                my_private_key)
         print("Shared hash: {}".format(self.shared_hash))
         key = list(self.shared_hash)
         random.shuffle(key)
         # Generate IV
         iv = bytes(str(key).encode()[:AES.block_size])
         # Convert hexstr to byte
         self.shared_hash = bytes.fromhex(self.shared_hash)
         # AES encrypt with CFB mode
         self.cipher = AES.new(self.shared_hash, AES.MODE_CFB, iv)
         self.hmac = HMAC.new(self.shared_hash, None, SHA256.new())
Example #10
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))
        # key encryption key
        # AES-256, might change the mode
        self.cipher = AES.new(shared_hash[:32], AES.MODE_CFB, shared_hash[32:48])

        #initialise a counter to prevent replay attacks
        #use the remaining bytes from the DH handshake so this value is secret
        self.counter = int(shared_hash[48:])

        #the server will generate a random key and send it via and encrypted channel
        if self.server:
            f = open("/dev/random", "rU")
            newkey = f.read(32)
            newiv = f.read(16)
            self.send(newkey)
            self.send(newiv)
        if self.client:
            newkey = self.recv()
            newiv = self.recv()
        #now build the content encryption cipher
        self.cipher = AES.new(newkey, AES.MODE_CFB, newiv)
Example #11
0
    def initiate_session(self):
        # Perform the initial connection handshake for 
        # agreeing on a shared secret
        ### TODO: Your code here!
        # This can be broken into code run just on the server 
        # or just on the client
        if self.server or self.client:

            # Create the DH key and store into these two variables
            # "my_private_key" is a
            # "my_public_key" is the g_a, 
            # which means g to the power of a mod p
            my_public_key, my_private_key = create_dh_key()

            # Send out public key
            # For client, it sends g_a as "my_public_key"
            self.send(bytes(str(my_public_key), "ascii"))
            
            # For server, receive public key g_a as "their_public_key"
            their_public_key = int(self.recv())

            # The following codes was designed to send g. 
            # However, according to rfc3521, the g should be 2, 
            # instead of a random number
            # Thus the codes has been abandoned
            '''
            # send client's g
            if self.client:
                self.send(bytes(str(my_public_key), "ascii"))
                self.send(bytes(str(g), "ascii"))
                their_public_key = int(self.recv())
            
            in the server,re calculate g_a
            if self.server:
                their_public_key = int(self.recv())
                g = int(self.recv())
                #print("g:",g)
                my_public_key = calculate_g_a(g,my_private_key)
                self.send(bytes(str(my_public_key), "ascii"))
            '''

            # Obtain hased shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))        

        # The original file use XOR one time padding and
        # we changed it to aes128, key size 16bytes, mode cfb       
        # Becuase the key size is 16 bytes, we take 16 bytes of 
        # the hashed shared key
        self.aes_key = shared_hash[:16]

        # set self.cipher object so that it will enter the "if" 
        # in "send" function
        self.cipher = AES.new(self.aes_key, AES.MODE_CFB, self.inital_vector)
Example #12
0
 def initiate_session(self):
     # Perform the initial connection handshake for agreeing on a shared secret 
     # This can be broken into code run just on the server or just on the clientasdsad
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key = int(self.recv())
         # Obtain our shared secret
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         # Take first 16 bytes of the (32 byte) hash as the key
         self.key = shared_hash[:16] 
         print("Shared hash: {}".format(shared_hash.hex()))
Example #13
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))
Example #14
0
 def initiate_session(self):
     # Perform the initial connection handshake for agreeing on a shared secret
     ### TODO: Your code here!
     # This can be broken into code run just on the server or just on the client
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key = int(self.recv())
         # Obtain our shared secret
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         print("Shared hash: {}".format(shared_hash))
         # Set the key to the shared hash (should it always be the first 16?)
         self.key = shared_hash
Example #15
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Default XOR algorithm can only take a key of length 32
        self.cipher = XOR.new(shared_hash[:4])
Example #16
0
 def initiate_session(self):
     # Perform the initial connection handshake for agreeing on a shared secret
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key = int(self.recv())
         # Obtain our shared secret and convert it to bytes.
         self.shared_hash = bytes.fromhex(
             calculate_dh_secret(their_public_key, my_private_key))
         print("Shared hash (in bytes): {}".format(self.shared_hash))
     # Our IV is the first 16 bytes of the shared key which is cryptographically secure
     iv = self.shared_hash[:16]
     # Our cipher is AES operating in CFB mode
     self.cipher = AES.new(self.shared_hash, AES.MODE_CFB, iv)
Example #17
0
    def initiate_session(self):
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.shared_key = calculate_dh_secret(their_public_key,
                                                  my_private_key)
            print("Shared hash: {}".format(self.shared_key))

        aes_key = self.shared_key[:32]
        #shortnening the value of aes_key to match the AES mode requirement
        self.iv = aes_iv()
        self.cipher = AES.new(aes_key, AES.MODE_CFB, self.iv)
Example #18
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(str(my_public_key))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            if self.verbose:
                print("Shared hash: {}".format(self.shared_hash))
            self.shared_hash = bytes.fromhex(self.shared_hash)

        # AES is used in CFB mode with an IV that is initialised each time send() is called
        iv = self.shared_hash[:16] # set the initialization vector
        self.cipher = AES.new(self.shared_hash, AES.MODE_CFB, iv) # create cipher object
Example #19
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        my_public_key, my_private_key = create_dh_key()

        # if I'm client. i.e., initialize the connection
        if self.client:
            # Simple rename to improve readability
            client_private_key, client_public_key = my_private_key, my_public_key

            # Send them our public key along with the IV
            IV = Random.new().read(AES.block_size)
            # msg structure: IV+msg
            clientInfo = b"".join([IV, bytes(str(client_public_key), 'ascii')])
            self.send(clientInfo)
            # Receive their public key
            server_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(server_public_key,
                                              client_private_key)

        # if I'm server. i.e., accept the connection
        elif self.server:
            # Rename
            server_private_key, server_public_key = my_private_key, my_public_key
            # only send them our publick key, let them choose the IV
            self.send(bytes(str(server_public_key), "ascii"))
            clientInfo = self.recv()
            IV = clientInfo[:AES.block_size]
            client_public_key = int(clientInfo[AES.block_size:])
            shared_hash = calculate_dh_secret(client_public_key,
                                              server_private_key)
        else:
            raise AttributeError("You have to be either a server or a client")

        # After the shared hash is obtained, we do three things:
        # 1. Derive AES key from it
        # 2. Generate HMAC with AES key
        # 3. Generate a PRNG using key as seed
        # As we are confident that the DH algorithm will protect the shared hash, we believe the key won't be compromised.
        key = shared_hash[:self.KEY_LENGTH]
        self.cipher = AES.new(key, AES.MODE_CFB, IV)
        self.hmac = HMAC.new(bytes(key, 'ascii'),
                             digestmod=SHA256.new())  # we use SHA256 here
        self.prng = aesg()
        self.prng.reseed(bytes(key, 'ascii'))
        print("session initialized")
Example #20
0
    def initiate_session(self):
        # The initial connection handshake for agreeing on a shared secret
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Sets the variables required for encryption and hashing
        IV = '\x16'*16
        shared_hash = bytes(shared_hash,"ascii")
        self.cipher = AES.new(shared_hash[:32], AES.MODE_CFB, IV)
        self.hmac = HMAC.new(shared_hash[:32])
Example #21
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(str(my_public_key))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            if self.verbose:
                print("Shared hash: {}".format(self.shared_hash))
            self.shared_hash = bytes.fromhex(self.shared_hash)

        # Use AES in CFB mode for encryption
        iv = self.shared_hash[:16] # set the initialization vector
        self.cipher = AES.new(self.shared_hash, AES.MODE_CFB, iv) # create cipher object
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Default XOR algorithm can only take a key of length 32

        #self.cipher = XOR.new(shared_hash[:4])
        self.cipher = AES.new(shared_hash[:32]) # AES-256 accepts keys of 32 bytes in length
Example #23
0
 def initiate_session(self):
     # Perform the initial connection handshake for agreeing on a shared secret
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         # Send them our public key
         self.send(bytes(str(my_public_key), "ascii"))
         # Receive their public key
         their_public_key = int(self.recv())
         # Obtain our shared secret
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         print("Shared hash: {}".format(shared_hash))
         # Seed the CSPRNG with our shared secret
         self.csprng.reseed(shared_hash.encode())
         # Generate a 256-bit AES key
         self.key = self.csprng.pseudo_random_data(SHA256.digest_size)
         # Set up a SHA256 HMAC with a 256-bit key generated by the CSPRNG
         self.hmac = HMAC.new(self.csprng.pseudo_random_data(32), None,
                              SHA256.new())
Example #24
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        #Sets the IV and key for the AES session from the hashed DH value
        iv = shared_hash[:16]
        key = shared_hash[:32]
        self.cipher = AES.new(key, AES.MODE_CFB, iv)
Example #25
0
    def hamc_sha256(strContent):
        h=hmac.new(skey.encoude(),strContent.encode(),hashlib.sha256)
        return base64.b64encode(h.digest())
         #pass

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the clientasdsad
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash.hex()))

        # Default XOR algorithm can only take a key of length 32
        self.cipher = XOR.new(shared_hash[:4])
Example #26
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Create a 128 bit counter from PyCrypto library.
        counter = Counter.new(128)
        # Creating AES cipher with 16 bit key, counter mode and the counter initialised
        # in previous line
        self.cipher = AES.new(shared_hash[:16], AES.MODE_CTR, counter = counter)
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), ch_enc_code))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

            # save hash in byte format for use as key
            self.shared_hash = bytes.fromhex(shared_hash)

        # Set the cipher_available equal to true so that
        # bot can use cipher with shraed_hash to encrypt and decrypt
        self.cipher_available = True
Example #28
0
 def initiate_session(self):
     if self.server or self.client:
         ###########Implement key exchange using Diffie-Hellman key exchange when peerto-peer connections are made between bots##############
         my_public_key, my_private_key = create_dh_key()
         self.send(bytes(str(my_public_key), "ascii"))
         # send them our public key
         their_public_key = int(self.recv())
         # receive their public key
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         # Obtain our shared secret
         print("shared hash is: {}".format(shared_hash))
         self.shared_hash = shared_hash
         # refer shared hash
         self.key = self.shared_hash[32:]
         # last 32 bytes of the shared hash is key
         print("self.key is: " + str(self.key))
         self.iv = self.shared_hash[16:]
         #  last 16 bytes of the shared hash is IV
         # IV is for Confidentiality of the channe
         print("self.key initiate_session is: " + str(self.iv))
         self.cipher = (self.key, AES.MODE_CBC, self.iv)
Example #29
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the clientasdsad
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash, shared_secret = calculate_dh_secret(
                their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash.hex()))

        self.mac = HMAC.new(shared_hash[:16])
        # Default XOR algorithm can only take a key of length 32
        iv = Random.new().read(AES.block_size)
        self.key = shared_hash[:16]
        self.cipher = AES.new(shared_hash[:16], AES.MODE_CBC, iv)
        #record msg and recive timestemp to prevent replay attack
        self.cache = [int(time.time()), ""]
Example #30
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        self.verbose = True
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(str(my_public_key))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.shared_hash = calculate_dh_secret(their_public_key,
                                                   my_private_key)
            if self.verbose:
                print(Fore.MAGENTA +
                      "[+] Shared hash: {}".format(self.shared_hash) +
                      Style.RESET_ALL)  #Print the shared key
                self.shared_hash = bytes.fromhex(self.shared_hash)

        # Use AES in CFB mode for encryption as its more secure than ECB. Also AES is used by the US Government
        iv = self.shared_hash[:16]  # set the initialization vector
        self.cipher = AES.new(self.shared_hash, AES.MODE_CFB,
                              iv)  # create cipher object
Example #31
0
 def initiate_session(self):
     if self.server or self.client:
         my_public_key, my_private_key = create_dh_key()
         self.send(bytes(str(my_public_key), "ascii"))
         # Send them our public key
         their_public_key = int(self.recv())
         # Receive their public key
         shared_hash = calculate_dh_secret(their_public_key, my_private_key)
         # Obtain our shared secret
         print("Shared hash: {}".format(shared_hash))
         # Prints shared hash on session establishment
         self.shared_hash = shared_hash
         # References shared hash
         self.key = self.shared_hash[32:]
         # Key is taken from the last 32 bytes of the shared key
         print("SELF.KEY is: " + str(self.key))
         # Prints self key as a string
         self.iv = self.shared_hash[16:]
         # IV is taken from the last 16 bytes of the shared key
         print("SELF.IV in INITIATE_SESSION is: " + str(self.iv))
         # Prints IV as string
         self.cipher = (self.key, AES.MODE_CBC, self.iv)
Example #32
0
	def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
		### TODO: Your code here!
		# This can be broken into code run just on the server or just on the client
		if self.server or self.client:
			my_public_key, my_private_key = create_dh_key()
			# Send them our public key
			self.send(bytes(str(my_public_key), "ascii"))
			# Receive their public key
			their_public_key = int(self.recv())
			# Obtain our shared secret
			self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)
			print("Shared hash: {}".format(self.shared_hash))
			self.salt = Random.new().read(64)	#randomly generate a 64 bit salt
			print("64 bit salt: " + str(self.salt) + "\n")
			derivedKey = KDF.PBKDF2(self.shared_hash,self.salt,32)	#generate derived key from salt, length should be 32 bits so that when split in 2, it provides a 16 bit key for AES
			print("32 bit derived key: " + str(derivedKey) + "\n");
			cipherKey, HMACkey = derivedKey[:16], derivedKey[16:]	#split derived key in half and use each 16 bit half as cipher and hmac key respectively
			print("16 bit cipher and hmac keys" + str(cipherKey) + ", " + str(HMACkey) + "\n")
			self.iv = Random.new().read(AES.block_size)	#randomly generate initialisation vector the size of the AES block size
			self.cipher = AES.new(cipherKey, AES.MODE_CBC, self.iv)	#generate cipher object with cipher key
			self.hashMAC = HMAC.new(HMACkey, digestmod = SHA512)	#generate HMAC object with HMAC key
Example #33
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the clientasdsad
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            self.shared_hash = shared_hash
            print("Shared hash: {}".format(shared_hash))
            #print("Shared hash length: {}".format(len(shared_hash)))

        #Using HC_256 stream cipher as a PRNG. Using shared_hash as seed of PRNG
        # to generate the 256-bit key and the 128-bit IV for this communication
        AES_key = HC_256(shared_hash)[:32]
        AES_iv = HC_256(shared_hash)[-16:]
        #Using AES encryption in CBC mode (block cipher)
        self.cipher = AES.new(AES_key, AES.MODE_CBC, AES_iv)
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Default XOR algorithm can only take a key of length 32
        # Creation of the initialisation vector using XOR algorithm and shared hash found in DH
        iv = XOR.new(shared_hash[:4])

        shared_secret = their_public_key * my_private_key

        #Cipher creation using AES mode CBC 
        self.cipher = AES.new(shared_secret, AES.MODE_CBC, iv)
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret 
        self.time_of_last_communication = datetime.datetime.now()
        # Project code here...
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Default XOR algorithm can only take a key of length 32
        # (4 byte) and thus is very insecure and impractical. Also bits can be changed
        # easily with stream ciphers. Hence, we've changed to a block cipher (CBC).
        # We are using AES-256 (key is 32 byte string).

        self.iv = shared_hash[:16]  # from week 04 lecture, block size is 128-bits. Using first 16 bytes of shared_hash.
        self.key = shared_hash[32:]  # from week 04 lecture, key length up to 256-bits. Using last 32 bytes of shared_hash.
        self.cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
Example #36
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        ### TODO: Your code here!
        # This can be broken into code run just on the server or just on the client
        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            print("Shared hash: {}".format(shared_hash))

        # Default XOR algorithm can only take a key of length 32
        # Creation of the initialisation vector using XOR algorithm and shared hash found in DH
        iv = XOR.new(shared_hash[:4])

        shared_secret = their_public_key * my_private_key

        #Cipher creation using AES mode CBC
        self.cipher = AES.new(shared_secret, AES.MODE_CBC, iv)
Example #37
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        # TODO: Your code here!
        # This can be broken into code run just on the server or just on the client

        # To avoid random number generated on the server and the client to coincide(if it happens), we choose different
        # range of integers
        if self.server:
            self.counter = random.randint(0, 10000000)

        if self.client:
            self.counter = random.randint(11000000, 50000000)

        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            self.shared_hash = calculate_dh_secret(their_public_key, my_private_key)

        self.keyExhangePerformed = True
Example #38
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret

        if self.server or self.client:
            my_public_key, my_private_key = create_dh_key()
            # Send them our public key
            self.send(bytes(str(my_public_key), "ascii"))
            # Receive their public key
            their_public_key = int(self.recv())
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)
            # print("Shared hash: {}".format(shared_hash))

        #Create Hmac
        self.hmac = HMAC.new(shared_hash, digestmod=SHA256)

        # Uses first 4 bytes of shared hash
        self.ctr = Counter.new(128,
                               initial_value=int.from_bytes(shared_hash[4:],
                                                            byteorder='big'))

        # Using CTR AES to encrypt with incrimenting counter thats the same on both ends
        self.cipher = AES.new(shared_hash, AES.MODE_CTR, counter=self.ctr)
Example #39
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        if not self.rsaKey:
            raise RuntimeError("Rsa key must be initialized")

        iv_length = AES.block_size
        dh_key_length = 256

        # client is the parent - has private rsaKey
        if self.client:
            if not self.rsaKey.has_private():
                raise RuntimeError("Client needs the private key")
            # initialize dh
            my_public_key, my_private_key = create_dh_key()
            # Receive the challenge from the child (iv g**a)
            encrypted_data = self.recv()
            tmpCipher = PKCS1_OAEP.new(self.rsaKey)
            decrypted_data = tmpCipher.decrypt(encrypted_data)
            if len(decrypted_data) < iv_length + 1 + dh_key_length:
                raise RuntimeError("Expected 'IV g**a'")
            self.iv = int.from_bytes(decrypted_data[:iv_length],
                                     byteorder='big')
            their_public_key = int.from_bytes(decrypted_data[iv_length + 1:],
                                              byteorder='big')
            # Respond to the challenge by the child (iv g**b signed)
            msg_to_be_signed = decrypted_data[:
                                              iv_length] + b' ' + my_public_key.to_bytes(
                                                  dh_key_length,
                                                  byteorder='big')
            h = SHA.new()
            h.update(msg_to_be_signed)
            signer = PKCS1_PSS.new(self.rsaKey)
            signature = signer.sign(h)
            # send the signed message
            self.send(msg_to_be_signed + bytes(' ', "ascii") + signature)
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)

        # server is the child - has public rsaKey
        if self.server:
            # Generate the IV
            self.iv = int.from_bytes(Random.new().read(iv_length),
                                     byteorder='big')
            # dh init
            my_public_key, my_private_key = create_dh_key()
            # send the challenge
            challenge = self.iv.to_bytes(
                AES.block_size, byteorder='big') + bytes(
                    ' ', "ascii") + my_public_key.to_bytes(dh_key_length,
                                                           byteorder='big')
            tmpCipher = PKCS1_OAEP.new(self.rsaKey)
            encrypted_data = tmpCipher.encrypt(challenge)
            self.send(encrypted_data)
            # verify the response
            response = self.recv()
            if len(response) < iv_length + 1 + dh_key_length + 2:
                raise RuntimeError("Expected 'IV g**b signed'")
            iv = int.from_bytes(response[:iv_length], byteorder='big')
            if iv != self.iv:
                raise RuntimeError("IV given was incorrect, challenge failed")
            # verify the signature
            msg_to_be_verified = response[:(iv_length + 1 + dh_key_length)]
            signature = response[(iv_length + 1 + dh_key_length + 1):]
            h = SHA.new()
            h.update(msg_to_be_verified)
            signer = PKCS1_PSS.new(self.rsaKey)
            if not signer.verify(h, signature):
                raise RuntimeError("Signature was incorrect, challenge failed")
            their_public_key = int.from_bytes(
                response[(iv_length + 1):(dh_key_length + iv_length + 1)],
                byteorder='big')
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)

        print("Shared hash: {}".format(shared_hash))
        # set up AES cipher
        self.cipher = AES.new(shared_hash, AES.MODE_CFB,
                              self.iv.to_bytes(iv_length, byteorder='big'))
        print("Authentication Successful")
Example #40
0
    def initiate_session(self):
        # Perform the initial connection handshake for agreeing on a shared secret
        if not self.rsaKey:
            raise RuntimeError("Rsa key must be initialized")

        iv_length = AES.block_size
        dh_key_length = 256

        # client is the parent - has private rsaKey
        if self.client:
            if not self.rsaKey.has_private():
                raise RuntimeError("Client needs the private key")
            # initialize dh
            my_public_key, my_private_key = create_dh_key()
            # Receive the challenge from the child (iv g**a)
            encrypted_data = self.recv()
            tmpCipher = PKCS1_OAEP.new(self.rsaKey)
            decrypted_data = tmpCipher.decrypt(encrypted_data)
            if len(decrypted_data) < iv_length + 1 + dh_key_length:
                raise RuntimeError("Expected 'IV g**a'")
            self.iv = int.from_bytes(decrypted_data[:iv_length], byteorder='big')
            their_public_key = int.from_bytes(decrypted_data[iv_length+1:], byteorder='big')
            # Respond to the challenge by the child (iv g**b signed)
            msg_to_be_signed = decrypted_data[:iv_length] + b' ' + my_public_key.to_bytes(dh_key_length, byteorder='big')
            h = SHA.new()
            h.update(msg_to_be_signed)
            signer = PKCS1_PSS.new(self.rsaKey)
            signature = signer.sign(h)
            # send the signed message
            self.send(msg_to_be_signed + bytes(' ',"ascii") + signature)
            # Obtain our shared secret
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)

        # server is the child - has public rsaKey
        if self.server:
            # Generate the IV
            self.iv = int.from_bytes(Random.new().read(iv_length), byteorder='big')
            # dh init
            my_public_key, my_private_key = create_dh_key()
            # send the challenge
            challenge = self.iv.to_bytes(AES.block_size, byteorder='big') + bytes(' ', "ascii") + my_public_key.to_bytes(dh_key_length, byteorder='big')
            tmpCipher = PKCS1_OAEP.new(self.rsaKey)
            encrypted_data = tmpCipher.encrypt(challenge)
            self.send(encrypted_data)
            # verify the response
            response = self.recv()
            if len(response) < iv_length + 1 + dh_key_length + 2:
                raise RuntimeError("Expected 'IV g**b signed'")
            iv = int.from_bytes(response[:iv_length], byteorder='big')
            if iv != self.iv:
                raise RuntimeError("IV given was incorrect, challenge failed")
            # verify the signature
            msg_to_be_verified = response[:(iv_length + 1 + dh_key_length)]
            signature = response[(iv_length + 1 + dh_key_length + 1):]
            h = SHA.new()
            h.update(msg_to_be_verified)
            signer = PKCS1_PSS.new(self.rsaKey)            
            if not signer.verify(h, signature):
                raise RuntimeError("Signature was incorrect, challenge failed")
            their_public_key = int.from_bytes(response[(iv_length+1):(dh_key_length + iv_length + 1)], byteorder='big')
            shared_hash = calculate_dh_secret(their_public_key, my_private_key)            

        print("Shared hash: {}".format(shared_hash))
        # set up AES cipher
        self.cipher = AES.new(shared_hash, AES.MODE_CFB, self.iv.to_bytes(iv_length, byteorder='big'));
        print("Authentication Successful")
Example #41
0
    def initiate_session(self):
        # spawn key material
        my_public_key, my_private_key = create_dh_key()
        # set some "magic numbers" - ie. "key material" sizes
        iv_length = AES.block_size
        key_length = 256
        sig_length = iv_length + key_length

        # if we are in "client" mode - we receive an encrypted-authentication package from the server.
        # the "client" has to extract an IV and a public key from the package, and use these materials
        # to create a "signature", which is appended to a message that is sent to the server.

        if self.client:
            # receive package
            encrypted_data = self.recv()
            # spawn the auth cipher and decrypt the package
            data = PKCS1_OAEP.new(self.rsa_key).decrypt(encrypted_data)
            # grab the iv from the start of the package
            self.iv = int.from_bytes(data[:iv_length], byteorder='big')
            # grab the public key from the back of the package
            their_public_key = int.from_bytes(data[iv_length + 1:],
                                              byteorder='big')
            # make a new message with the IV and OUR OWN public key
            message = data[:iv_length] + b' ' + my_public_key.to_bytes(
                key_length, byteorder='big')
            h = SHA.new()
            # hash the message
            h.update(message)
            # spawn an rsa signature and sign it with the hashed message and append the signature to the message
            # --> send message to server (send function has encryption)
            self.send(message + bytes(' ', "ascii") +
                      PKCS1_PSS.new(self.rsa_key).sign(h))

        # if we are in "server" mode - we generate our own IV and package it with our public key material.
        # this message is encrypted and sent to the "client".
        # the IV's of the returned message and our own can be compared directly to preserve integrity

        if self.server:
            # spawn initialization vector
            self.iv = int.from_bytes(Random.new().read(iv_length),
                                     byteorder='big')
            # concatenate the iv and the server public key
            message = self.iv.to_bytes(iv_length, byteorder='big') + bytes(
                ' ', "ascii") + my_public_key.to_bytes(key_length,
                                                       byteorder='big')
            # spawn the auth cipher, encrypt the message and send
            self.send(PKCS1_OAEP.new(self.rsa_key).encrypt(message))
            # wait for response
            response = self.recv()
            # IV integrity check
            if int.from_bytes(response[:iv_length],
                              byteorder='big') != self.iv:
                raise RuntimeError("Poisoned IV")
            # spawn hash
            h = SHA.new()
            # peel off the signature
            h.update(response[:(sig_length + 1)])
            # spawn signer
            signer = PKCS1_PSS.new(self.rsa_key)
            # signature integrity check
            if not signer.verify(h, response[(sig_length + 2):]):
                raise RuntimeError("...This isn't the master...")
            # we extract the client's public key
            their_public_key = int.from_bytes(response[(iv_length +
                                                        1):(sig_length + 1)],
                                              byteorder='big')

        # spawn the shared secret
        shared_hash = calculate_dh_secret(their_public_key, my_private_key)
        print("Shared hash: {}".format(shared_hash))

        # spawn the cipher using gathered keying materials
        self.cipher = AES.new(shared_hash, AES.MODE_CFB,
                              self.iv.to_bytes(iv_length, byteorder='big'))
        print("Authentication Successful")