我有这个python套接字编码的问题,客户端/服务器无法正常运行

时间:2017-11-20 01:18:03

标签: python sockets unix aes

当我尝试编写代码函数时,我收到400错误,但是,我正在寻找250个好的成功消息。不同的消息旨在显示程序是否正常运行。这有两个部分:客户端代码和服务器代码。

有什么可能导致此问题的建议?

客户端服务器代码

# Client to implement simplified RSA algorithm.
# The client says hello to the server, and the server responds with a Hello
# and its public key. The client then sends a session key encrypted with the
# server's public key. The server responds to this message with a nonce
# encrypted with the server's public key. The client decrypts the nonce
# and sends it back to the server encrypted with the session key. Next,
# the server sends the client a message with a status code. If the status code
# is "250" then the client can ask for the server to roll the dice. Otherwise,
# the client's connection to the server will be terminated.


#!/usr/bin/python3

import socket
import math
import random
import sys
import time
import simplified_AES


def expMod(b,n,m):
    """Computes the modular exponent of a number returns (b^n mod m)"""
    if n==0:
        return 1
    elif n%2==0:
        return expMod((b*b)%m, n/2, m)
    else:
        return(b*expMod(b,n-1,m))%m

def RSAencrypt(m, e, n):
    """Encryption side of RSA"""

    return expMod(m,e,n)  ## Add code to encrypt. You _must_ use the expMod method. 
    ##return 3
def RSAdecrypt(c, d, n):
    """Decryption side of RSA"""
    return expMod(c,d,n) ## Add code to decrypt. You _must_ use the expMod method.

def serverHello():
    """Sends server hello message"""
    status = "100 Hello"
    return status

def sendSessionKey(s):
    """Sends server session key"""
    status = "110 SessionKey " + str(s)
    return status

def sendTransformedNonce(xform):
    """Sends server nonce encrypted with session key"""
    status = "130 Transformed Nonce " + str(xform)
    return status

def computeSessionKey():
    """Computes this node's session key"""
    sessionKey = random.randint(1, 65536)
    return sessionKey

def serverHello():
    """Generates server hello message"""
    status = "100 Hello"
    return status

def RollDice():
    """Generates message to get server to roll some or all dice."""
    toRoll = input('Enter dice to roll separated by commas: ')
    status = "200 Roll Dice " + str(toRoll)
    return status

# s       = socket
# msg     = initial message being processed
# state   = dictionary containing state variables
def processMsgs(s, msg, state):
    """This function processes messages that are read through the socket. It
        returns a status, which is an integer indicating whether the operation
        was successful"""

    status = -2
    rcvr_mod = int(state['modulus'])            # Receiver's modulus for RSA
    rcvr_exp = int(state['pub_exp'])            # Receiver's public exponent
    symmetricKey = int(state['SymmetricKey'])   # shared symmetric key
    rolls = int(state['Rolls'])                 # Number of dice rolls used

    strTest = "101 Hello "
    if (strTest in msg and status==-2):
        print("Message received: "+ msg)
        RcvdStr = msg.split(' ')
        rcvr_mod = int(RcvdStr[2]) # Modulus for public key encryption
        rcvr_exp = int(RcvdStr[3]) # Exponent for public key encryption
        print("Server's public key: ("+ str(rcvr_mod)+","+str(rcvr_exp)+")")
        symmetricKey = computeSessionKey()
        ## Add code to handle the case where the symmetricKey is
        ## greater than the modulus.
        while(symmetricKey>rcvr_mod):
            symmetricKey = computeSessionKey()
            print("Symmetric Key: ",symmetricKey)


        encSymmKey = RSAencrypt(symmetricKey,rcvr_exp,rcvr_mod)
        print("Encrypted Symmetric Key: ",encSymmKey)
        msg = sendSessionKey(encSymmKey)
        print(msg)
        s.sendall(bytes(msg,'utf-8'))
        state['modulus'] = rcvr_mod
        state['pub_exp'] = rcvr_exp
        state['SymmetricKey'] = symmetricKey
        status = 1

    strNonce = "120 Nonce"
    if (strNonce in msg and status==-2):
        print("Message received: " + msg)
        RcvdStr = msg.split(' ')
        encNonce = int(RcvdStr[2])
        nonce = RSAdecrypt(encNonce,rcvr_exp,rcvr_mod)
        """Setting up for Simplified AES encryption"""
        plaintext = nonce
        simplified_AES.keyExp(symmetricKey) # Generating round keys for AES.
        ciphertext = simplified_AES.encrypt(plaintext) # Running simplified AES.
        msg = sendTransformedNonce(ciphertext)
        s.sendall(bytes(msg,'utf-8'))
        status = 1

    strDiceRoll = "205 Roll Dice ACK"
    if (strDiceRoll in msg and status==-2):
        print("Message received: " + msg)
        DiceValues = msg[18:].split(',')
        if rolls < 2:
            WantstoRollMore = input("Do you wish to roll more dice? (y/n): ")
            if WantstoRollMore=='y':
                msg = RollDice()
                s.sendall(bytes(msg,'utf-8'))
                rolls += 1
                status = 1
            else:
                status = 0
        else:
            status = 0
        state['Rolls'] = rolls            

    strSuccess = "250 OK"
    strFailure = "400 Error"
    if (strFailure in msg and status==-2):
        print("Message received: " + str(msg))
        status = 0 # To terminate loop at client
    if (strSuccess in msg and status==-2):
        print("Cryptographic checks completed successfully")
        print(msg)
        if rolls ==0:
            msg = "200 Roll Dice"
        else:
            msg = RollDice()
        s.sendall(bytes(msg,'utf-8'))
        rolls += 1
        status = 1

    if status==-2:
        print("Incoming message was not processed. \r\n Terminating")
        status = -1
    return status

def main():
    """Driver function for the project"""
    args = sys.argv
    if len(args) != 3:
        print ("Please supply a server address and port.")
        sys.exit()
    serverHost = str(args[1])       # The remote host
    serverPort = int(args[2])       # The same port as used by the server

    print("Client of Aaron")
    print('''
    The dice in this program are numbered from 0--4.
    No error checking is done, so ensure that the dice numbers are correct.
    If you do not want to enter any dice, simply hit the enter key.
    ''')

    # Bogus values that will be overwritten with values read from the socket.
    sndr_exp = 3
    sndr_mod = 60769
    symmKey = 32767
    rolls = 0
    state = {'modulus': sndr_mod, 'pub_exp': sndr_exp, 'SymmetricKey': symmKey,
             'Rolls': rolls }

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((serverHost, serverPort))
    msg = serverHello()
    s.sendall(bytes(msg,'utf-8'))
    status = 1
    while (status==1):
        msg = s.recv(1024).decode('utf-8')
        if not msg:
            status = -1
        else:
            status = processMsgs(s, msg, state)
    if status < 0:
        print("Invalid data received. Closing")
    s.close()

if __name__ == "__main__":
    main()

对于服务器

# Server to implement simplified RSA algorithm. 
# The server waits for the client to say Hello. Once the client says hello,
# the server sends the client a public key. The client uses the public key to
# send a session key with confidentiality to the server. The server then sends
# a nonce (number used once) to the client, encrypted with the server's private
# key. The client decrypts that nonce and sends it back to server encrypted 
# with the session key. Next, the server sends the client a message with a
# status code. If the status code is "250" then the client can ask for the
# server to roll the dice. Otherwise, the server's connection to the client
# will be terminated.

# Author: 620098870 2017-11-09

#!/usr/bin/python3

import socket
import random
import math
import hashlib
import time
import sys
import simplified_AES

def expMod(b,n,m):
    """Computes the modular exponent of a number"""
    """returns (b^n mod m)"""
    if n==0:
        return 1
    elif n%2==0:
        return expMod((b*b)%m, n/2, m)
    else:
        return(b*expMod(b,n-1,m))%m

def RSAencrypt(m, e, n):
    """Encryption side of RSA"""
    return expMod(m,e,n)       ## Add code here to do encryption

def RSAdecrypt(c, d, n):
    """Decryption side of RSA"""
    return expMod(c,d,n)    ## Add code here to do decryption

def gcd(u, v):
    """Iterative Euclidean algorithm"""
    while v !=0:
       u, v = v, u % v
    return abs(u)

    ## Write code to compute the gcd of two integers

def ext_Euclid(m,n):
    """Extended Euclidean algorithm"""

    ## Write code to implement the Extended Euclidean algorithm. See Tutorial 7
    ## This method should return the multiplicative inverse of n mod m.
    ## i.e., (n*n^(-1) mod m = 1
    ## If this method returns a negative number add m to that number until
    ## it becomes positive.

    (a1,a2,a3)=(1,0,m)
    (b1,b2,b3) = (0,1,n) ## i.e., (n*e^(-1) mod m =1
    while True:
        if b3 ==0:
            return a3
        if b3 == 1:
            b2 = ((n**1)%m)
            return b2
        q=math.floor(a3/b3)
        (t1,t2,t3) = (a1-q*b1,a2-q*b2,a3-q*b3)
        (a1,a2,a3) = (b1,b2,b3)
        (b1,b2,b3)=(t1,t2,t3) ## it becomes possitve


def generateNonce():
    """This method returns a 16-bit random integer derived from hashing the
        current time. This is used to test for liveness"""
    hash = hashlib.sha1()
    hash.update(str(time.time()).encode('utf-8'))
    return int.from_bytes(hash.digest()[:2], byteorder=sys.byteorder)

def findE(phi, p, q):
    """Method to find e given phi, p, and q"""
    """while loop to increment e until it is relatively prime to phi"""
    ## Add code to find e given phi, p, and q
    e=2
    phi=(p-1)*(q-1)
    while  (gcd(e,phi)!=1):
        e+=1
    return e 



def findE(phi):
    """Method to randomly choose a good e given phi"""
    e = random.randint(1, phi)
    return e

def genKeys(p, q):
    """Generate n, phi(n), e, and d."""
    n = p*q ## Complete this
    phi = (p-1) * (q-1)## Complete this
    e = findE(phi)## Complete this
    d =  ext_Euclid(phi,e)## Complete this
    if (d<0):
        d += phi


    print ("n = "+ str(n))
    print ("phi(n) = "+ str(phi))
    print ("e = "+ str(e))
    print ("d = "+ str(d))
    print
    return n, e, d    

def clientHelloResp(n, e):
    """Responds to client's hello message with modulus and exponent"""
    status = "101 Hello "+ str(n) + " " + str(e)
    return status

def SessionKeyResp(nonce):
    """Responds to session key with nonce"""
    status = "120 Nonce "+ str(nonce)
    return status

def nonceVerification(nonce, decryptedNonce):
    """Verifies that the transmitted nonce matches that received
       from the client."""
    if (nonce == decryptedNonce):
        status = "250 OK"
    else:
        status = "400 Error"
    return status

def clientHello():
    """Generates client hello message"""
    status = "100 Hello"
    return status

def rollDice(dice, toRoll=[0,1,2,3,4]):
    """Rolls specified dice. If no dice are specified, all dice are rolled."""
    for i in toRoll:
        dice[i] = random.randint(1,6)

def RollDiceACK(dice):
    """Generates message with dice values"""
    strDice = ','.join([str(x) for x in dice])
    status = "205 Roll Dice ACK " + strDice
    return status

# s      = socket
# msg     = initial message being processed
# state  = dictionary containing state variables
def processMsgs(s, msg, state):
    """This function processes messages that are read through the socket. It
        returns a status, which is an integer indicating whether the operation
        was successful"""
    status = -2
    modulus = int(state['modulus'])          # modulus   = modulus for RSA
    pub_exp = int(state['pub_exp'])          # pub_exp   = public exponent
    priv_exp = int(state['priv_exp'])        # priv_exp  = secret key
    challenge = int(state['nonce'])          # challenge = nonce sent to client
    SymmKey = int(state['SymmetricKey'])     # SymmKey   = shared symmetric key
    rolls = int(state['Rolls'])              # rolls     = number of dice rolls
    dice  = state['Dice']                    # Dice      = values of dice
    dice = list(map(int,dice))               # Converting dice values to ints

    strTest = "100 Hello"
    if strTest in msg and status == -2:
        print("Message received: " + msg)
        msg = clientHelloResp(modulus, pub_exp)
        s.sendall(bytes(msg,'utf-8'))
        status = 1

    strSessionKey = "110 SessionKey"
    if strSessionKey in msg and status == -2:
        print("Message received: "+ msg)
        RcvdStr = msg.split(' ')
        encSymmKey = int(RcvdStr[2])
        SymmKey = RSAdecrypt(encSymmKey,pub_exp,modulus)## Add code to decrypt symmetric key
        state['SymmetricKey'] = SymmKey
        # The next line generates the round keys for simplified AES
        simplified_AES.keyExp(SymmKey)
        challenge = generateNonce()
        # Add code to ensure that the challenge can always be encrypted
        challenge = RSAencrypt(challenge,pub_exp,modulus)
        print('Challenge: ' + str(challenge)) #  correctly with RSA.
        state['nonce'] = challenge
        msg = SessionKeyResp(RSAdecrypt(challenge, pub_exp, modulus))
        s.sendall(bytes(msg, 'utf-8'))
        status = 1

    strSessionKeyResp = "130 Transformed Nonce"
    if strSessionKeyResp in msg and status == -2:
        print("Message received: " + msg)
        RcvdStr = msg[22:] 
        encryptedChallenge = int(RcvdStr)
        # The next line runs AES decryption to retrieve the key.
        decryptedChallenge = simplified_AES.decrypt(encryptedChallenge)
        msg = nonceVerification(challenge, decryptedChallenge)
        s.sendall(bytes(msg,'utf-8'))
        status = 1

    strDiceRollResp = "200 Roll Dice"
    if strDiceRollResp in msg and status == -2:
        print("Message received: " + msg)
        RcvdStr = msg[14:]
        if (len(RcvdStr)>0):
            RcvdStrParams = RcvdStr.split(',')
            toRoll = list(map(int,RcvdStrParams))
            rollDice(dice, toRoll)
        else:
            rollDice(dice)
        if (rolls<3):
            status = 1
        else:
            status = 0
        rolls += 1
        state['Dice'] = dice
        state['Rolls'] = rolls 
        msg = RollDiceACK(dice)
        s.sendall(bytes(msg,'utf-8'))

    # status can only be -2 if none of the other branches were followed
    if status==-2:
        print("Incoming message was not processed. \r\n Terminating")
        status = -1
    return status

def main():
    """Driver function for the project"""
    args = sys.argv
    if len(args) != 2:
        print ("Please supply a server port.")
        sys.exit()
    HOST = ''               # Symbolic name meaning all available interfaces
    PORT = int(args[1])     # The port on which the server is listening
    if PORT < 1023 or PORT > 65535:
        print("Invalid port specified.")
        sys.exit()
    print ("Enter prime numbers. One should be between 907 and 1013, and\
 the other between 53 and 67")
    p = int(input('Enter P : '))
    q = int(input('Enter Q: '))
    n, e, d = genKeys(p, q)

    random.seed()
    SymmKey = 1013    # Initializing symmetric key with a bogus value.
    nonce = generateNonce()
    dice = [random.randint(1,6), random.randint(1,6), random.randint(1,6),
            random.randint(1,6),random.randint(1,6)]

    rolls = 0    
    state = {'nonce': nonce, 'modulus': n, 'pub_exp': e, 'priv_exp': d,
    'SymmetricKey': SymmKey, 'Rolls': rolls, 'Dice': dice}

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((HOST, PORT))
        s.listen(1)
        conn, addr = s.accept()
        with conn:
            print('Connected by', addr)
            status = 1
            while (status==1):
                msg = conn.recv(1024).decode('utf-8')
                if not msg:
                    status = -1
                else:
                    status = processMsgs(conn, msg, state)
            if status < 0:
                print("Invalid data received. Closing")
            conn.close()
            print("Closed connection socket")

if __name__ == "__main__":
    main()

0 个答案:

没有答案