Exemple #1
0
def generate_keys():
    dh = DiffieHellman()
    private_key, public_key = dh.get_private_key(), dh.gen_public_key()
    return jsonify({
        "private_key": private_key,
        "public_key": public_key,
    })
Exemple #2
0
class Person35(Person34):
    def start(self):
        print self.name, 'Starting experiment'
        self.dh = DiffieHellman()
        self.other.rcv_msg1(self.dh.p, self.dh.g)

    def rcv_msg1(self, p, g):
        self.dh = DiffieHellman(p=p, g=g)
        self.other_dh = DiffieHellman(p=p, g=g)
        self.other.rcv_msg2('ACK')

    def rcv_msg2(self, msg):
        assert msg == 'ACK'
        self.other.rcv_msg3(self.dh.public)

    def rcv_msg3(self, A):
        self.other_dh.public = A
        print self.name, 'generating shared secret'
        self.shared_secret = self.dh.exchange(self.other_dh)
        self.key = self.make_key(self.shared_secret)
        self.other.rcv_msg4(self.dh.public)

    def rcv_msg4(self, B):
        self.other_dh = DiffieHellman(p=self.dh.p, g=self.dh.g, public=B)
        print self.name, 'generating shared secret'
        self.shared_secret = self.dh.exchange(self.other_dh)
        self.key = self.make_key(self.shared_secret)
        iv = keygen()
        enc_iv = cbc_encrypt(self.msg, self.key, iv) + iv
        print self.name, 'sending', self.msg
        self.other.rcv_msg5(enc_iv)

    def rcv_msg5(self, enc_iv):
        rec_iv = enc_iv[-16:]
        rec_enc = enc_iv[:-16]
        rec_msg = cbc_decrypt(rec_enc, self.key, rec_iv)
        print self.name, 'received', rec_msg

        iv = keygen()
        enc = cbc_encrypt(rec_msg, self.key, iv)
        print self.name, 'sending', rec_msg
        self.other.rcv_msg6(enc + iv)

    def rcv_msg6(self, enc_iv):
        iv = enc_iv[-16:]
        enc = enc_iv[:-16]
        msg = cbc_decrypt(enc, self.key, iv)
        print self.name, 'received', msg
 def logInUser(self, **kwargs):
     """Server Side logIn User
     User sends his username (Unique Identifier) and his password
     Security: Message from user ciphered with Server Public Key
     Session Management: Create a Public Key with DiffieHellman"""
     # Decipher the Message with Server Private Key
     receivedData = dm.decryptMessageReceived(kwargs['data'].decode('hex'))
     print receivedData['userID']
     # Verify if the user exists and has finished the regist process
     if DBmodule.db_registAuthenticate(receivedData['userID']) and \
         DBmodule.db_getLogIn(receivedData['userID'], receivedData['password']) == 1:
         # Create Session
         print receivedData['userID']
         print receivedData['password']
         serverSession = DiffieHellman.DiffieHellman()
         # Create challenge
         token = os.urandom(20)
         um.addSession(receivedData['userID'], serverSession, token)
         # Send to client the Token and the session public key
         tf = tempfile.NamedTemporaryFile(delete=True)
         pub_key = DBmodule.db_getUserPubKey(
             DBmodule.db_getUserID(receivedData['userID'])).decode('hex')
         security.encrypt_RSA(security.importkey_RSA(pub_key), token, tf)
         messageToSend = {
             'token': tf.read().encode('hex'),
             'session': serverSession.publicKey
         }
         return json.dumps(messageToSend)
     elif DBmodule.db_registNotAuthenticate(receivedData['userID']):
         return "REGIST_AGAIN"
     else:
         return "ERROR"
Exemple #4
0
def request_start_dh(data):
    """Client is requesting a communication.

    Receive P and G for Diffie-Hellman
    """
    STORAGE['dh'] = DiffieHellman(p_g=data)
    logger.info('Client connected. Recieved DH request, sending public key')

    return 'MY_PUBLIC,{0}'.format(STORAGE['dh'].get_my_public())
Exemple #5
0
 def rcv_msg4(self, B):
     self.other_dh = DiffieHellman(p=self.dh.p, g=self.dh.g, public=B)
     print self.name, 'generating shared secret'
     self.shared_secret = self.dh.exchange(self.other_dh)
     self.key = self.make_key(self.shared_secret)
     iv = keygen()
     enc_iv = cbc_encrypt(self.msg, self.key, iv) + iv
     print self.name, 'sending', self.msg
     self.other.rcv_msg5(enc_iv)
Exemple #6
0
def generate_shared_key():
    try:
        local_private_key = request.args.get("local_private_key")
        remote_public_key = request.args.get("remote_public_key")
    except:
        return jsonify({"message": "Invalid parameters"}), 400
    try:
        shared_key = DiffieHellman.gen_shared_key_static(
            local_private_key, remote_public_key)
    except:
        return jsonify({"message": "Invalid public key"}), 400
    return jsonify({"shared_key": shared_key})
Exemple #7
0
 def BeginExchange(self, data):
 	self.match_nonce = os.urandom(SafeSlingerExchange.NONCE_LEN)
 	self.wrong_nonce = os.urandom(SafeSlingerExchange.NONCE_LEN)
 	# match_extrahash = sha3(match_nonce)
 	self.match_extrahash = CryptoEngine.sha3_digest(self.match_nonce)
 	# wrong_hash = sha3(wrong_nonce)
 	self.wrong_hash = CryptoEngine.sha3_digest(self.wrong_nonce)
 	# match_hash = sha3(match_extrahash)
 	self.match_hash = CryptoEngine.sha3_digest(self.match_extrahash)
 	# encrypted_data = aes_cbc(enckey, exchange_data)
 	self.encrypted_data = CryptoEngine.aes256_cbc_encryption(data, self.match_nonce)
 	#compute protocol_commitment = sha3(match_hash||wrong_hash)
 	self.protocol_commitment = CryptoEngine.sha3_digest(self.match_hash + self.wrong_hash)
 	# generate Diffie Hellman Key
 	self.dhkey = DiffieHellman()
 	self.dhpubkey = self.dhkey.getHexData(self.dhkey.publicKey).strip()
 	self.dhkey_len = len(self.dhpubkey)
 	# data_commitment = sha3(protocol_commitment||DHPubKey||encrypted_data)
 	self.data_commitment = CryptoEngine.sha3_digest(self.protocol_commitment+self.dhpubkey+self.encrypted_data)
 	# initialize network object
 	self.httpclient = HTTPClient(self.address)
Exemple #8
0
 def configure(self, data):
     p, g, ya, xb, yb, zz = [data[key] for key in ('P', 'G', 'YstatCAVS', 'XstatIUT', 'YstatIUT', 'Z')]
     dh = DiffieHellman(g, p, ya)
     dh.my_private_key = xb
     return dh, yb, zz
Exemple #9
0
 def start(self):
     print self.name, 'Starting experiment'
     self.dh = DiffieHellman()
     self.other.rcv_msg1(self.dh.p, self.dh.g)
Exemple #10
0
def logInUser(userID, password, card):
    """Function for Logging into the server. handled server-side
    Security: Encrypted with Server Public Key
    """
    register_openers().add_handler(
        urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
    try:
        pwd = security.PBKDKF2.pwsend(password)
        params = {'userID': userID, 'password': pwd}
        sendparam = encryptMessageToSendRSA(params)
        datagen, headers = multipart_encode(sendparam)
        request = urllib2.Request('https://localhost:8080/logInUser', datagen,
                                  headers)
        result = urllib2.urlopen(request).read()
        if result == "ERROR":
            return False
        elif result == "REGIST_AGAIN":
            return False
        else:
            clientSession = DiffieHellman.DiffieHellman()
            # receive token and decrypt it with
            private_file = os.path.join('PrivateKeys',
                                        'Private_key_' + str(userID))
            with open(private_file, 'rb') as f:
                private_key = security.importkey_RSA(f.read())
                loginMessage = json.loads(result)
                receivedMessage = security.decrypt_RSA(
                    private_key, loginMessage['token'].decode('hex'))
                # sign token
                """ -----------------SIGN CC/PrivateKey By PWD -------------------- """
                reply = card.connect(0l)
                if reply:
                    tokenSigned = card.sign(receivedMessage)
                    card.disconnect()
                else:
                    tokenSigned = ""
                """ -----------------SIGN CC/PrivateKey By PWD -------------------- """
                message = {'userID': userID, 'password': pwd}
                # send token back
                tokenchiphered = encryptMessageToSendRSA(
                    {'token': tokenSigned})
                sendparam = encryptMessageToSendRSA(message)
                messageToSend = {
                    'message': sendparam,
                    'session': json.dumps(clientSession.publicKey),
                    'token': tokenchiphered
                }
                datagen, headers = multipart_encode(messageToSend)
                request = urllib2.Request(
                    'https://localhost:8080/authTokenValidation', datagen,
                    headers)
                result = urllib2.urlopen(request).read()
                if result == "OK":
                    # Establish Session
                    clientSession.genKey(loginMessage['session'])
                    destination = os.path.join('download', 'session.txt')
                    user = User(userID, clientSession.getKey().encode('hex'))
                    print "Logged In: " + str(userID)

                    return user
                return False
    except urllib2.URLError as e:
        print e.reason
        print 'Currently, you are not a valid user!\nSafeBox Team'
        return False
Exemple #11
0
 def rcv_msg1(self, p, g):
     self.dh = DiffieHellman(p=p, g=g)
     self.other_dh = DiffieHellman(p=p, g=g)
     self.other.rcv_msg2('ACK')
Exemple #12
0
def client():
    """Client mode work flow."""
    downlink = Connection('downlink', 'r')
    uplink = Connection('uplink', 'w+')

    # Establish connection
    dh = DiffieHellman()
    p, g = dh.get_pg()
    uplink.send('INIT,{0},{1}'.format(p, g))

    response = get_response(downlink, 'MY_PUBLIC', 2,
                            'Failed to authenticate via DH')

    public = dh.get_my_public()
    uplink.send('MY_PUBLIC,{0}'.format(public))
    key = dh.compute_shared(response[1])

    logging.debug('Key established: {0}'.format(key.hexdigest()))

    # Start encrypted communication
    response = get_response(downlink, 'AES', 2, 'Failed to start AES')
    aes = AES.new(key.digest(), AES.MODE_CBC, b64decode(response[1]))

    # Verify identity using FFS
    while True:
        ffs = FFSProver()
        # Send X
        msg = msg_encrypt(aes, str(ffs.get_x()))
        uplink.send('FFS_X,{0}'.format(msg))
        # Get A vector
        response = get_response(downlink, 'FFS_A', 2,
                                'Failed to verify identity via FFS')
        a_vector = [int(a) for a in msg_decrypt(aes, response[1])]
        # Solve Y
        msg = msg_encrypt(aes, str(ffs.solve(a_vector)))
        uplink.send('FFS_Y,{0}'.format(msg))
        # Get result
        response = next(downlink.receive())
        if response not in ('FFS_OK', 'FFS_DONE'):
            raise RuntimeError('Failed to verify identity via FFS')
        if response == 'FFS_DONE':
            break

    # Send messages
    print('Connection established, communication channel open.')
    print('If you want to end this program press CTRL(C')
    while True:
        # Snd message
        raw_msg = raw_input('Enter message: ')
        msg = msg_encrypt(aes, raw_msg)
        uplink.send('MSG,{0}'.format(msg))

        # Get response
        response = next(downlink.receive())
        response = response.split(',')

        if len(response) != 2 or response[0] != 'SHA256':
            raise RuntimeError('Channel compromised')

        # Compare Hashes
        our_hash = sha256(raw_msg).hexdigest()
        their_hash = msg_decrypt(aes, response[1])
        print('Recieved: ' + their_hash)

        if their_hash != our_hash:
            print('Hash mismatch!')
            raise RuntimeError('Channel compromised')
        else:
            print('Hash matches')
Exemple #13
0
    def associate(self):
        assoc_type = request.form.get('openid.assoc_type')
        if assoc_type not in ('HMAC-SHA1', 'HMAC-SHA256'):
            return err_response(
                error="Unknown association type requested",
                error_code="unsupported-type",
                assoc_type="HMAC-SHA256",
                session_type="DH-SHA256",
            )

        session_type = request.form.get('openid.session_type')
        if session_type == 'no-encryption':
            # TODO: support no-encryption if we can tell we're on SSL?
            return err_response(
                error="Session type no-encryption is not supported on non-HTTPS connections",
                error_code="unsupported-type",
                assoc_type="HMAC-SHA256",
                session_type="DH-SHA256",
            )
        if session_type not in ('DH-SHA1', 'DH-SHA256'):
            return err_response(
                error="Unknown session type requested",
                error_code="unsupported-type",
                assoc_type="HMAC-SHA256",
                session_type="DH-SHA256",
            )

        mac_key = os.urandom(20 if assoc_type == 'HMAC-SHA1' else 32)
        assoc_handle = b64encode(os.urandom(20))
        expires = datetime.utcnow() + timedelta(seconds=1000)

        logging.debug("Formed a shared association %s with key %r!", assoc_handle, mac_key)

        cur = g.db_conn.cursor()
        cur.execute("INSERT INTO openid_associations (handle, private, secret, assoc_type, expires) VALUES (%s, false, %s, %s, %s)",
            (assoc_handle, bytearray(mac_key), assoc_type, expires))
        g.db_conn.commit()
        cur.close()

        dh_mod = request.form.get('openid.dh_modulus')
        dh_gen = request.form.get('openid.dh_gen')
        if dh_mod is not None:
            dh_mod = unbtwoc(b64decode(dh_mod))
        if dh_gen is not None:
            dh_gen = unbtwoc(b64decode(dh_gen))

        try:
            dh_consumer_public = request.form['openid.dh_consumer_public']
        except KeyError:
            return err_response(error="Required parameter dh_consumer_public not provided")
        dh_consumer_public = unbtwoc(b64decode(dh_consumer_public))

        dh = DiffieHellman(dh_gen, dh_mod, dh_consumer_public)
        dh.select_key()
        dh_server_public = b64encode(btwoc(dh.calculate_public_key()))
        dh_secret = dh.calculate_secret()
        logging.debug("Calculated our shared secret is %r", dh_secret)

        hasher = hashlib.sha1 if session_type == 'DH-SHA1' else hashlib.sha256
        hashed_session_key = hasher(btwoc(dh_secret)).digest()
        logging.debug("Hashed session key is %r", hashed_session_key)
        cipher_key_bytes = xor(hashed_session_key, mac_key)
        logging.debug("Ciphered key bytes are %r", cipher_key_bytes)
        enc_mac_key = b64encode(cipher_key_bytes)
        logging.debug("Base64-encoded ciphered key bytes are %r", enc_mac_key)

        return direct_response(
            assoc_type=assoc_type,
            session_type=session_type,
            assoc_handle=assoc_handle,
            expires_in=1000,
            dh_server_public=dh_server_public,
            enc_mac_key=enc_mac_key,
        )
Exemple #14
0
msg, addr = sock.recvfrom(1024)
data = unwrap(msg, crypto.DEFAULT_KEY)
assert(data is not None)
assert(len(data['chunks']) == 1)
RHello = data['chunks'][0]
if RHello[0] != 0x70: print hexlify(msg), data
assert(RHello[0] == 0x70)
assert(RHello[1] == len(RHello[2]))
(taglen, msg) = vread(RHello[2])
assert(taglen == 16)
assert(msg[:16] == '0123456789ABCDEF')
(cookielen, msg) = vread(msg[16:])
cookie = msg[:cookielen]

# ignore RHello options, the server will be using an ephemeral key
dh = DiffieHellman()
pcert = '\x1d\x02' + packl(dh.publicKey)
pcert = vwrite(len(pcert)) + pcert
sknc = '\x02\x1d\x02\x03\x1a\x00\x00\x02\x1e\x00'
msg = '1234' + vwrite(cookielen) + cookie + vwrite(len(pcert)) + pcert + vwrite(len(sknc)) + sknc + 'X'

IIKeying = prep("\x38" + struct.pack('!H', len(msg)) + msg, 0, 3, crypto.DEFAULT_KEY)
sock.sendto(IIKeying, (UDP_IP, UDP_PORT))

msg, addr = sock.recvfrom(1024)
data = unwrap(msg, crypto.DEFAULT_KEY)
assert(data is not None)
assert(len(data['chunks']) == 1)
RIKeying = data['chunks'][0]
assert(RIKeying[0] == 0x78)
assert(RIKeying[1] == len(RIKeying[2]))
import hashlib
import secrets
from dh import DiffieHellman


def gen_hmac(msg, key):  # takes ints
    return hashlib.sha256((str(key) + str(msg)).encode()).hexdigest()


def test_hmac(msg, key, hmac):  # takes ints
    return hashlib.sha256((str(key) + str(msg)).encode()).hexdigest() == hmac


C = DiffieHellman(
    int(
        "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff",
        16), 2)  # A
S = DiffieHellman(
    int(
        "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff",
        16), 2)  # B

# client and server agree beforehand
N = int(
    "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff",
    16)
g = 2
k = 3
I = "*****@*****.**"
P = "password"
Exemple #16
0
 def GroupDHComputation(self):
 	# Doing DH group key construction
 	position = 0
 	currentKeyNodeNumber = 0
 	firstKeynode = True
 	self.uidSet.sort()
 	for x in self.uidSet:
 		if x == self.userID:
 			break
 		else:
 			position += 1
 	
 	# If position 1 or 0
 	# print "position = %d" % position
 	if position < 2:
 		# If 1 set keynode 1 to be pubkey 0 and vice versa
 		currentKeyNodeNumber = 2
 		self.keyNodes[1] = bytearray(self.dhpubkeySet[self.uidSet[1-position]])
 	else:
 		# Check if you have the keynode corresponding to you position.
 		try:
 			elem = self.keyNodes[position]
 		except KeyError:
 			datagram = self.httpclient.sync_keynodes(self.userID)
 			self.handleSyncKeyNodes(datagram)
 			return
 		currentKeyNodeNumber = position+1
 	
 	currentKeynode = DiffieHellman()
 	sharedKey = None
 	
 	while currentKeyNodeNumber <= len(self.uidSet):
 		#For the first keynode that you generate use your private key and keynode as public key
 		if firstKeynode:
 			pubKey = int(binascii.hexlify(self.keyNodes[currentKeyNodeNumber-1]), 16)
 			sharedKey = self.dhkey.genSecret(self.dhkey.privateKey, pubKey)
 			firstKeynode = False
 		else:
 			pubKey = int(binascii.hexlify(bytearray(self.dhpubkeySet[self.uidSet[currentKeyNodeNumber-1]])), 16)
 			sharedKey = self.dhkey.genSecret(currentKeynode.privateKey, pubKey)
 		
 		# Storing generated shared key in DH struct for key node, currentKeynode->priv_key = sharedKey
 		currentKeynode.privateKey = sharedKey
 		
 		# If position 1 or 0
 		if position < 2 and currentKeyNodeNumber < len(self.uidSet):
 			# Send exponentiated keynode to server
 			expKeyNode = pow(currentKeynode.generator, currentKeynode.privateKey, currentKeynode.prime)
 			hex_string = hex(expKeyNode)
 			expKeyNodeRaw = hex_string[2:-1].decode("hex")
 			datagram = self.httpclient.sync_requestkeynodes(self.userID, 
 			                                                self.uidSet[currentKeyNodeNumber],
 			                                                expKeyNodeRaw)
 		
 		currentKeyNodeNumber += 1
 	
 	# compute group DH key
 	hex_string = hex(sharedKey).strip()
 	#print "sharedKey: %s" % hex_string[2:-1]
 	self.groupkey = hex_string[2:-1].decode("hex")
 	del sharedKey
 	self.SyncMatch()
Exemple #17
0
class SafeSlingerExchange:
    # constants
    MINI_USERS = 2
    NONCE_LEN = 32

    def __init__(self, address="slinger-dev.appspot.com"):
        # networking object
        self.version = 1 << 24 | 8 << 16
        self.address = address
        self.httpclient = None
        # predefined data structures
        self.match_nonce = None
        self.wrong_nonce = None
        self.match_extrahash = None
        self.match_hash = None
        self.encrypted_data = None
        self.protocol_commitment = None
        self.dhkey = None
        self.dhpubkey = None
        self.data_commitment = None
        self.num_users = 0
        self.userID = None
        self.correct_index = -1
        self.selected_index = -1
        self.dhkey_len = -1
        self.groupkey = None
        self.uidSet = []
        self.dataCommitmentSet = {}
        self.protoCommitmentSet = {}
        self.dhpubkeySet = {}
        self.receivedcipherSet = {}
        self.matchExtraHashSet = {}
        self.wrongHashSet = {}
        self.matchHashSet = {}
        self.keyNodes = {}
        self.matchNonceSet = {}
        # load dictionary files
        ins = open( "odd-dict.txt", "r" )
        self.odd_array = []
        for line in ins:
            self.odd_array.append( line.rstrip() )
        ins.close()
        ins = open( "even-dict.txt", "r" )
        self.even_array = []
        for line in ins:
    	    self.even_array.append( line.rstrip() )
    	ins.close()
    
    def SelecGroupSize(self):
    	while True:
    		try:
    			numUsers = int(raw_input("How many users in the exchange? [2-10] "))
    			if numUsers >= 2 and numUsers <=10:
    				self.num_users = numUsers
    				break
    			else:
    				print "A minimum of %d members are required to exchange data." % SafeSlingerExchange.MINI_USERS
    		except Exception:
    			print "A minimum of %d members are required to exchange data." % SafeSlingerExchange.MINI_USERS
    
    def BeginExchange(self, data):
    	self.match_nonce = os.urandom(SafeSlingerExchange.NONCE_LEN)
    	self.wrong_nonce = os.urandom(SafeSlingerExchange.NONCE_LEN)
    	# match_extrahash = sha3(match_nonce)
    	self.match_extrahash = CryptoEngine.sha3_digest(self.match_nonce)
    	# wrong_hash = sha3(wrong_nonce)
    	self.wrong_hash = CryptoEngine.sha3_digest(self.wrong_nonce)
    	# match_hash = sha3(match_extrahash)
    	self.match_hash = CryptoEngine.sha3_digest(self.match_extrahash)
    	# encrypted_data = aes_cbc(enckey, exchange_data)
    	self.encrypted_data = CryptoEngine.aes256_cbc_encryption(data, self.match_nonce)
    	#compute protocol_commitment = sha3(match_hash||wrong_hash)
    	self.protocol_commitment = CryptoEngine.sha3_digest(self.match_hash + self.wrong_hash)
    	# generate Diffie Hellman Key
    	self.dhkey = DiffieHellman()
    	self.dhpubkey = self.dhkey.getHexData(self.dhkey.publicKey).strip()
    	self.dhkey_len = len(self.dhpubkey)
    	# data_commitment = sha3(protocol_commitment||DHPubKey||encrypted_data)
    	self.data_commitment = CryptoEngine.sha3_digest(self.protocol_commitment+self.dhpubkey+self.encrypted_data)
    	# initialize network object
    	self.httpclient = HTTPClient(self.address)
    
    def AssignUser(self):
    	datagram = self.httpclient.assign_user(self.data_commitment)
    	userID = (struct.unpack("!i", datagram[0:4]))[0]
    	self.userID = userID
    	# store parameters
    	self.dataCommitmentSet[userID] = self.data_commitment
    	self.protoCommitmentSet[userID] = self.protocol_commitment
    	self.dhpubkeySet[userID] = self.dhpubkey
    	self.receivedcipherSet[userID] = self.encrypted_data
    	print ("Assigned ID = %d.\n\nThis number is used to create a unique group of users. Compare, and then enter the lowest number." % self.userID )
    
    def SelectLowestNumber(self):
    	low_num = -1
    	while True:
    		try:
    			low_num = int(raw_input("Enter Lowest Number: "))
    			if low_num > 0: 
    				break
    			else:
    				print 'Please enter a positive integer.'
    		except Exception:
    			print 'Please enter a positive integer.'
    	
    	print "%d users, Lowest %d\nRequesting Membership..." % (self.num_users, low_num)
    	numUsers_Recv = 1
    	self.uidSet[:] = []
    	self.uidSet.insert(0, self.userID)
    	retry = 0
    	while (numUsers_Recv < self.num_users):
    		datagram = self.httpclient.send_minid(self.userID, 
    		                                      low_num, 
    		                                      self.uidSet, 
    		                                      self.data_commitment)
    		minVersion = (struct.unpack("!i", datagram[0:4]))[0]
    		count = (struct.unpack("!i", datagram[4:8]))[0]
    		delta_count = (struct.unpack("!i", datagram[8:12]))[0]
    		# Collect all data commitments Ci from other users
    		if delta_count > 0:
    			offset = 12
    			for i in range(delta_count):
    				uid = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				self.uidSet.append(uid)
    				offset += 4
    				commitLen = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				offset += 4
    				self.dataCommitmentSet[uid] = struct.unpack("%dB" %commitLen, datagram[offset:offset+commitLen])
    				offset += commitLen
    				numUsers_Recv += 1
    				print "Received (%d/%d) Items" % (numUsers_Recv, self.num_users-1)
    		retry += 1
    		time.sleep(retry)
    		if retry >= 10:
    			print "Error: reached maximum retries"
    			quit()
    	self.SyncData()
    
    def SyncData(self):
    	print "Waiting for all users to join..."
    	numUsers_Recv = 1
    	self.uidSet[:] = []
    	self.uidSet.insert(0, self.userID)
    	retry = 0
    	while (numUsers_Recv < self.num_users):
    		datagram = self.httpclient.sync_data(self.userID,
    		                                    self.uidSet,
    		                                    self.protocol_commitment,
    		                                    self.dhpubkey,
    		                                    self.encrypted_data)
    		count = (struct.unpack("!i", datagram[0:4]))[0]
    		delta_count = (struct.unpack("!i", datagram[4:8]))[0]
    		# Collect all data commitments Ci from other users
    		if delta_count > 0:
    			offset = 8
    			for i in range(delta_count):
    				uid = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				self.uidSet.append(uid)
    				offset += 4 # proto commitment
    				total_len = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				offset += 4
    				self.protoCommitmentSet[uid] = struct.unpack("%dB" % SafeSlingerExchange.NONCE_LEN, datagram[offset:offset+SafeSlingerExchange.NONCE_LEN])
    				offset += SafeSlingerExchange.NONCE_LEN
    				#dhkey
    				self.dhpubkeySet[uid]  = struct.unpack("%dB" % self.dhkey_len, datagram[offset:offset+self.dhkey_len])
    				offset += self.dhkey_len
    				# encrypted_dataSet
    				encrypted_len = total_len-SafeSlingerExchange.NONCE_LEN-self.dhkey_len
    				self.receivedcipherSet[uid] = struct.unpack("%dB" % encrypted_len, datagram[offset:offset+encrypted_len])
    				offset += encrypted_len
    				numUsers_Recv += 1
    				print "Received (%d/%d) commitments" % (numUsers_Recv, self.num_users)
    		retry += 1
    		time.sleep(retry)
    		if retry >= 10:
    			print "Error: reached maximum retries"
    			quit()
    
    
    def Compute3Wordphrases(self):
    	#compute 3-word phrases, step 1 compute hash
    	total_len = 0
    	self.uidSet.sort()
    	buffer = bytearray()
    	
    	for x in self.uidSet:
    		buffer.extend(self.protoCommitmentSet[x])
    		buffer.extend(self.dhpubkeySet[x])
    		buffer.extend(self.receivedcipherSet[x])
    	
    	#print 'buffer: ', binascii.hexlify(buffer)
    	wordhash = CryptoEngine.sha3_digest(bytes(buffer))
    	#print 'word hash: ', binascii.hexlify(wordhash)
    	del buffer
    	
    	# generate 3-word phrases
    	hashint = [0, 0, 0, 0, 0, 0]
    	# create empty byte array
    	evenVec = bytearray(256)
    	oddVec = bytearray(256)
    	evenVec[ord(wordhash[0])] = 1 # set to True
    	oddVec[ord(wordhash[1])] = 1
    	evenVec[ord(wordhash[2])] = 1
    	
    	# essentially need to sort list of user ids first
    	# generate wordlist for every user id up to ours
    	# then generate our wordlist
    	count = 0
    	foundUser = False
    	hasharray = None
    	decoy1 = None
    	decoy2 = None
    	
    	for x in self.uidSet:
    		if x == self.userID: foundUser = True
    		# unsigned char *buf = malloc(HASHLEN + 1); 
    		buf = bytearray()
    		buf.append(count)
    		buf.extend(wordhash)
    		whash = CryptoEngine.sha3_digest(bytes(buf))
    		hasharray = bytearray(whash)
    		del buf
    		
    		# 2 decoy wordlists for each user
    		for d in range(2):
    			while evenVec[hasharray[0 + 3*d]] == 1:
    				if hasharray[0 + 3*d] == 255: hasharray[0 + 3*d] = hasharray[0 + 3*d] - 255
    				else: hasharray[0 + 3*d] = hasharray[0 + 3*d] + 1
    			while oddVec[hasharray[1 + 3*d]] == 1:
    				if hasharray[1 + 3*d] == 255: hasharray[1 + 3*d] = hasharray[1 + 3*d] - 255
    				else: hasharray[1 + 3*d] = hasharray[1 + 3*d] + 1
    			while evenVec[hasharray[2+ 3*d]] == 1:
    				if hasharray[2 + 3*d] == 255: hasharray[2 + 3*d] = hasharray[2 + 3*d] - 255
    				else: hasharray[2 + 3*d] = hasharray[2 + 3*d] + 1
    			#print 'modified hasharray hash: ', binascii.hexlify(hasharray), 'len:', len(hasharray)
    			evenVec[hasharray[0+3*d]] = 1
    			oddVec[hasharray[1+3*d]] = 1
    			evenVec[hasharray[2+3*d]] = 1     
    			# compute decoy strings only if user is found
    			if (d == 0) and (foundUser == True):
    				hashint[0] = hasharray[0]
    				hashint[1] = hasharray[1]
    				hashint[2] = hasharray[2]
    				decoy1 = "%s   %s   %s" % (self.even_array[hashint[0]], self.odd_array[hashint[1]], self.even_array[hashint[2]])
    			elif foundUser == True:
    				hashint[3] = hasharray[3]
    				hashint[4] = hasharray[4]
    				hashint[5] = hasharray[5]
    				decoy2 = "%s   %s   %s" %(self.even_array[hashint[3]], self.odd_array[hashint[4]], self.even_array[hashint[5]])
    		#end of d loop
    		if foundUser == True: break
    		count = count + 1
    	#end of x loop
    	
    	# to set the correct wordlist at some random position
    	self.correct_index = random.randint(0, sys.maxint) % 3
    	#print 'correct_index = ', self.correct_index
    	
    	d1Added = False
    	wordlist_labels = []
    	numberlist_labels = []
    	hashbytes = bytearray(wordhash)
    	number = 0
    	# numeric labels
    	for i in range(3):
    		numberstr = ''
    		if i == self.correct_index:
    			for j in range(3):
    				number = hashbytes[j]
    				if (j % 2) != 0: number = number + 256
    				number = number + 1
    				numberstr = numberstr+"%d   "%(number)
    		else:
    			if not d1Added:
    				for j in range(3):
    					number = hashint[j]
    					if (j % 2) != 0: number = number + 256
    					number = number + 1
    					numberstr = numberstr+"%d   "%(number)
    				d1Added = True
    			else:
    				for j in range(3):
    					number = hashint[j+3]
    					if (j % 2) != 0: number = number + 256
    					number = number + 1
    					numberstr = numberstr+"%d   "%(number)
    		numberlist_labels.append(numberstr)
    	
    	d1Added = False
    	for i in range(3):
    		if i == self.correct_index:
    			# correct phrases
    			correct_phrase = "%s   %s   %s" % (self.even_array[hashbytes[0]], self.odd_array[hashbytes[1]], self.even_array[hashbytes[2]])
    			wordlist_labels.append(correct_phrase)
    		else:
    			if not d1Added:
    				wordlist_labels.append(decoy1)
    				d1Added = True
    			else:
    				wordlist_labels.append(decoy2)
    	print "All phones must match one of the 3-word phrases. Compare, and then pick the matching phrase."
    	print "[-1]: No Match."
    	for i in range(3):
    		print "[%d]: %s (%s)" % (i, wordlist_labels[i], numberlist_labels[i])
    	while True:
    		try:
    			idx = int(raw_input("Enter the index number to show your decision:"))
    			if idx <= 2 and idx >= -1 : 
    				self.selected_index = idx
    				break
    			else:
    				print 'Enter a correct index!'
    		except Exception:
    			print 'Not an integer number!'
    	print "Waiting for verification from all members..."
    
    def PhrasesVerification(self):
    	if self.selected_index == self.correct_index:
    		numUsers_Recv = 1
    		del self.uidSet[:]
    		self.uidSet.insert(0, self.userID)
    		while (numUsers_Recv < self.num_users):
    			datagram = self.httpclient.sync_signatures(self.userID,
    			                                           self.uidSet,
    			                                           self.match_extrahash,
    			                                           self.wrong_hash)
    			# match_extrahash || wrong_hash
    			count = (struct.unpack("!i", datagram[0:4]))[0]
    			delta_count = (struct.unpack("!i", datagram[4:8]))[0]
    			# Collect all data commitments Ci from other users
    			if delta_count > 0:
    				offset = 8
    				for i in range(delta_count):
    					uid = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    					self.uidSet.append(uid)
    					offset += 4
    					# proto commitment
    					total_len = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    					offset += 4
    					# Nmh
    					Nmh = struct.unpack("%dB" % SafeSlingerExchange.NONCE_LEN, datagram[offset:offset+SafeSlingerExchange.NONCE_LEN])
    					offset += SafeSlingerExchange.NONCE_LEN
    					# Sha3Nmh
    					Sha3Nmh = CryptoEngine.sha3_digest(bytes(bytearray(Nmh)))
    					# wH
    					wH = struct.unpack("%dB" % SafeSlingerExchange.NONCE_LEN, datagram[offset:offset+SafeSlingerExchange.NONCE_LEN])
    					offset += SafeSlingerExchange.NONCE_LEN
    					buf = bytearray(Sha3Nmh)
    					buf.extend(wH)
    					cPC = CryptoEngine.sha3_digest(bytes(buf))
    					del buf
    					rPC = self.protoCommitmentSet[uid]
    					# verify if protocol commitments match
    					# also make sure that neither is nil
    					if cPC == bytearray(rPC):
    						print "Recievd (%d/%d) Match nonces" % (numUsers_Recv, self.num_users)
    						self.matchExtraHashSet[uid] = Nmh
    						self.wrongHashSet[uid] = wH
    						self.matchHashSet[uid] = Sha3Nmh
    					else:
    						print "Someone reported a difference in phrases. Begin the exchange again."
    						return False
    					numUsers_Recv += 1
    		return True
    	else:
    		ret = self.httpclient.sync_signatures(self.userID,
    		                                      self.uidSet,
    		                                      self.match_hash,
    		                                      self.wrong_nonce)
    		return False
    		
    def handleSyncKeyNodes(self, datagram):
    	position = 0
    	for x in self.uidSet:
    		if x == self.userID:
    			break
    		else:
    			position += 1
    	
    	if position == 0 or position == 1:
    		return
    	else:
    		keyNodeFound = (struct.unpack("!i", datagram[0:4]))[0]
    		if keyNodeFound > 0:
    			keyNodeLen = (struct.unpack("!i", datagram[4:8]))[0]
    			keyNodeData = struct.unpack("%dB" % keyNodeLen, datagram[8:8+keyNodeLen])
    			self.keyNodes[position] = bytearray(keyNodeData)
    			self.GroupDHComputation()
    		else:
    			datagram = self.httpclient.sync_keynodes(self.userID)
    			self.handleSyncKeyNodes(datagram)
    
    def GroupDHComputation(self):
    	# Doing DH group key construction
    	position = 0
    	currentKeyNodeNumber = 0
    	firstKeynode = True
    	self.uidSet.sort()
    	for x in self.uidSet:
    		if x == self.userID:
    			break
    		else:
    			position += 1
    	
    	# If position 1 or 0
    	# print "position = %d" % position
    	if position < 2:
    		# If 1 set keynode 1 to be pubkey 0 and vice versa
    		currentKeyNodeNumber = 2
    		self.keyNodes[1] = bytearray(self.dhpubkeySet[self.uidSet[1-position]])
    	else:
    		# Check if you have the keynode corresponding to you position.
    		try:
    			elem = self.keyNodes[position]
    		except KeyError:
    			datagram = self.httpclient.sync_keynodes(self.userID)
    			self.handleSyncKeyNodes(datagram)
    			return
    		currentKeyNodeNumber = position+1
    	
    	currentKeynode = DiffieHellman()
    	sharedKey = None
    	
    	while currentKeyNodeNumber <= len(self.uidSet):
    		#For the first keynode that you generate use your private key and keynode as public key
    		if firstKeynode:
    			pubKey = int(binascii.hexlify(self.keyNodes[currentKeyNodeNumber-1]), 16)
    			sharedKey = self.dhkey.genSecret(self.dhkey.privateKey, pubKey)
    			firstKeynode = False
    		else:
    			pubKey = int(binascii.hexlify(bytearray(self.dhpubkeySet[self.uidSet[currentKeyNodeNumber-1]])), 16)
    			sharedKey = self.dhkey.genSecret(currentKeynode.privateKey, pubKey)
    		
    		# Storing generated shared key in DH struct for key node, currentKeynode->priv_key = sharedKey
    		currentKeynode.privateKey = sharedKey
    		
    		# If position 1 or 0
    		if position < 2 and currentKeyNodeNumber < len(self.uidSet):
    			# Send exponentiated keynode to server
    			expKeyNode = pow(currentKeynode.generator, currentKeynode.privateKey, currentKeynode.prime)
    			hex_string = hex(expKeyNode)
    			expKeyNodeRaw = hex_string[2:-1].decode("hex")
    			datagram = self.httpclient.sync_requestkeynodes(self.userID, 
    			                                                self.uidSet[currentKeyNodeNumber],
    			                                                expKeyNodeRaw)
    		
    		currentKeyNodeNumber += 1
    	
    	# compute group DH key
    	hex_string = hex(sharedKey).strip()
    	#print "sharedKey: %s" % hex_string[2:-1]
    	self.groupkey = hex_string[2:-1].decode("hex")
    	del sharedKey
    	self.SyncMatch()
    
    def SyncMatch(self):
    	self.match_nonce = CryptoEngine.aes256_cbc_encryption(self.match_nonce, self.groupkey)
    	numUsers_Recv = 1
    	del self.uidSet[:]
    	self.uidSet.insert(0, self.userID)
    	retry = 0
    	while (numUsers_Recv < self.num_users):
    		datagram = self.httpclient.sync_match(self.userID,
    		                                      self.uidSet,
    		                                      self.match_nonce)
    		count = (struct.unpack("!i", datagram[0:4]))[0]
    		delta_count = (struct.unpack("!i", datagram[4:8]))[0]
    		# Collect all data commitments Ci from other users
    		if delta_count > 0:
    			offset = 8
    			for i in range(delta_count):
    				uid = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				self.uidSet.append(uid)
    				offset += 4
    				total_len = (struct.unpack("!i", datagram[offset:offset+4]))[0]
    				offset += 4
    				keyNonce = struct.unpack("%dB" % total_len, datagram[offset:offset+total_len])
    				keyNonce = CryptoEngine.aes256_cbc_decryption(keyNonce, self.groupkey)
    				nh = CryptoEngine.sha3_digest(bytes(keyNonce))
    				meh = self.matchExtraHashSet[uid]
    				if nh == bytearray(meh):
    					self.matchNonceSet[uid] = keyNonce
    				else:
    					print "An error occurred during commitment verification."
    					quit()
    				offset += total_len
    				numUsers_Recv += 1
    		retry += 1
    		time.sleep(retry)
    		if retry >= 10:
    			print "Error: reached maximum retries"
    			quit()
    
    
    def ObtainGatherData(self):
    	# decrypted the final data
    	_decrypted = {}
    	for x in self.uidSet:
    		if x == self.userID: continue
    		individualData = CryptoEngine.aes256_cbc_decryption(self.receivedcipherSet[x], self.matchNonceSet[x])
    		_decrypted[x] = individualData
    	return _decrypted
    
    def __del__(self):
    	
    	self.httpclient.close()
    	del self.httpclient
    	
    	# predefined data structures
    	del self.match_nonce
    	del self.wrong_nonce
    	del self.match_extrahash
    	del self.match_hash
    	del self.encrypted_data
    	del self.protocol_commitment
    	del self.dhkey
    	del self.data_commitment
    	del self.userID
    	del self.groupkey
    	
    	del self.uidSet
    	del self.dataCommitmentSet
    	del self.protoCommitmentSet
    	del self.dhpubkeySet
    	del self.receivedcipherSet
    	del self.matchExtraHashSet
    	del self.wrongHashSet
    	del self.matchHashSet
    	del self.keyNodes
    	del self.matchNonceSet
    	
    	# load dictionary files
    	del self.odd_array
    	del self.even_array
import hashlib
import secrets
from Crypto.Cipher import AES
from dh import DiffieHellman

# normal protocol
alice = DiffieHellman(int("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 16), 2)
bob = DiffieHellman(int("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 16), 2)
p = alice.p 
g = alice.g
A = alice.get_public_key()
B = bob.get_public_key()
s = alice.get_shared_key(B)
key = hashlib.sha256(s.to_bytes(2 ** 16, "little")).hexdigest()[:32] # 16 bytes
alice_iv = secrets.token_bytes(16)
bob_iv = secrets.token_bytes(16)
alice_cipher = AES.new(bytes.fromhex(key), AES.MODE_CBC, alice_iv)
alice_to_bob = alice_cipher.encrypt(b"YELLOW SUBMARINE") + alice_iv 
print(alice_to_bob)
bob_cipher = AES.new(bytes.fromhex(key), AES.MODE_CBC, alice_to_bob[-16:])
bob_decrypted = bob_cipher.decrypt(alice_to_bob)
print(bob_decrypted)
bob_cipher = AES.new(bytes.fromhex(key), AES.MODE_CBC, bob_iv)
bob_to_alice = bob_cipher.encrypt(bob_decrypted[:-16]) + bob_iv
print(bob_to_alice)

# mitm attack
alice = DiffieHellman(int("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 16), 2)
bob = DiffieHellman(int("ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff", 16), 2)
p = alice.p 
g = alice.g
Exemple #19
0
msg, addr = sock.recvfrom(1024)
data = unwrap(msg, crypto.DEFAULT_KEY)
assert (data is not None)
assert (len(data['chunks']) == 1)
RHello = data['chunks'][0]
if RHello[0] != 0x70: print hexlify(msg), data
assert (RHello[0] == 0x70)
assert (RHello[1] == len(RHello[2]))
(taglen, msg) = vread(RHello[2])
assert (taglen == 16)
assert (msg[:16] == '0123456789ABCDEF')
(cookielen, msg) = vread(msg[16:])
cookie = msg[:cookielen]

# ignore RHello options, the server will be using an ephemeral key
dh = DiffieHellman()
pcert = '\x1d\x02' + packl(dh.publicKey)
pcert = vwrite(len(pcert)) + pcert
sknc = '\x02\x1d\x02\x03\x1a\x00\x00\x02\x1e\x00'
msg = '1234' + vwrite(cookielen) + cookie + vwrite(
    len(pcert)) + pcert + vwrite(len(sknc)) + sknc + 'X'

IIKeying = prep("\x38" + struct.pack('!H', len(msg)) + msg, 0, 3,
                crypto.DEFAULT_KEY)
sock.sendto(IIKeying, (UDP_IP, UDP_PORT))

msg, addr = sock.recvfrom(1024)
data = unwrap(msg, crypto.DEFAULT_KEY)
assert (data is not None)
assert (len(data['chunks']) == 1)
RIKeying = data['chunks'][0]