pyCrypto for linux and windows

This is the place for queries that don't fit in any of the other categories.

pyCrypto for linux and windows

Postby newbi3 » Sun Apr 21, 2013 1:05 am

I am a computer science student working on a python shell. It consists of a Server and Client pair and all of the communication is encrypted with AES using the pycrypto libraries. Everything works great if I am running the Server and Client on the same OS (ex. Running the server on windows and the client on windows) the problem occurs when I run the server on a linux machine and the client on a windows machine. Suddenly I get this error:

Code: Select all
ValueError: Input strings must be a multiple of 16 in length


I understand the meaning of it but why am I only getting it when I am running each pair on different OS's? I made sure that I am using pycrypto 2.6 and python 2.7 on each machine.

Here is the full error:

Code: Select all
Traceback (most recent call last):
  File "Server.py", line 78, in <module>
    startServer()
  File "Server.py", line 18, in startServer
    getShell(conn)
  File "Server.py", line 30, in getShell
    print recvDecrypted(socket, 32768)
  File "Server.py", line 37, in recvDecrypted
    received = decryptAES(socket.recv(size))
  File "Server.py", line 57, in decryptAES
    decoded = DecodeAES(cipher, string)
  File "Server.py", line 56, in <lambda>
    DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
  File "/usr/local/lib/python2.7/dist-packages/Crypto/Cipher/blockalgo.py", line 295, in decrypt
    return self._cipher.decrypt(ciphertext)
ValueError: Input strings must be a multiple of 16 in length


Server Code:
Code: Select all
import socket
from Crypto.Cipher import AES
import base64

def startServer():
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.bind(("", 5050))
   
   print "Server started"
   
   while 1:
      s.listen(5)
      conn, addr = s.accept()
      print "Client connected"
      getShell(conn)

def getShell(socket):
        while(1):
                cmd = raw_input(recvDecrypted(socket, 1024) + " ")
                if (cmd == "exit"):
                        sendEncrypted(socket, "exit")
                        break
                sendEncrypted(socket, cmd)
                print recvDecrypted(socket, 32768)


def sendEncrypted(socket, message):
        socket.send(encryptAES(str(message)))

def recvDecrypted(socket, size):
        received = decryptAES(socket.recv(size))
        return str(received)

def encryptAES(string):                                                                     
        BLOCK_SIZE = 32                                                                               
        PADDING = '`'                                                                           
        pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING                               
        secretKey = "g$yhdfh68h$gdjr6ue456dv$^%gdncTh"                                                   
        cipher = AES.new(secretKey)                                                                 
        EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
        encoded = EncodeAES(cipher, string)
        return encoded

def decryptAES(string):
        BLOCK_SIZE = 32
        PADDING = '`'
        pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
        secretKey = "g$yhdfh68h$gdjr6ue456dv$^%gdncTh"
        cipher = AES.new(secretKey)
        DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
        decoded = DecodeAES(cipher, string)
        return decoded

   
startServer()



Client Code:
Code: Select all
import socket
import time
import os
import subprocess
from Crypto.Cipher import AES
import base64
import getpass

def startClient():
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   
   s.connect(("127.0.0.1", 5050))
   createShell(s)

def createShell(socket):
        time.sleep(.25)
        startingDir = os.getcwd()
        while(1):
                sendEncrypted(socket, getpass.getuser() + "@" + os.getcwd() + "$")
                cmd = str(recvDecrypted(socket, 1024))
                print cmd
                cmd = cmd.split(" ")
                if (cmd[0] == "cd"):
                        if (len(cmd) == 1):
                                os.chdir(os.path.expanduser("~"))
                                sendEncrypted(socket, " ")
                        else:
                                if (os.path.isdir(cmd[1])):
                                        os.chdir(cmd[1])
                                        sendEncrypted(socket, " ")
                                else:
                                        sendEncrypted(socket, "No such directory")
                elif (cmd[0] == "exit"):
                        break
                else:
                        execout = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
                        sendEncrypted(socket, execout.stdout.read() + execout.stderr.read())
                time.sleep(.025)
        os.chdir(startingDir)


def sendEncrypted(socket, message):
        socket.send(encryptAES(str(message)))

def recvDecrypted(socket, size):
        received = decryptAES(socket.recv(size))
        return received

def encryptAES(string):                                                                                   # Encrypt with AES
        BLOCK_SIZE = 32                                                                                         # Size of the cipher
        PADDING = '`'                                                                                           # Add to string if needed
        pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING                                        # Add the padding
        secretKey = "g$yhdfh68h$gdjr6ue456dv$^%gdncTh"                                                          # The key
        cipher = AES.new(secretKey)                                                                             # Create the cipher
        EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))                                            # Encrypt string s with cipher c
        encoded = EncodeAES(cipher, string)                                                                     # Get encrypted string
        return encoded                                                                                          # Return value

def decryptAES(string):                                                                                   # Decrypt AES
        BLOCK_SIZE = 32
        PADDING = '`'
        pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
        secretKey = "g$yhdfh68h$gdjr6ue456dv$^%gdncTh"
        cipher = AES.new(secretKey)
        DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
        decoded = DecodeAES(cipher, string)
        return decoded

startClient()
newbi3
 
Posts: 2
Joined: Sun Apr 21, 2013 12:51 am

Re: pyCrypto for linux and windows

Postby setrofim » Sun Apr 21, 2013 8:59 am

  • Try using socket.sendall() instead of socket.send().
  • Log what is being sent and what is being received and compare the results to figure out what is going on.
  • The argument passed to recv method is the buffer size. The actual size of the data received can be less; therefore you should always explicitly check the size of received data in situations where it matters.
  • Unless your assignment specifically requires you to use sockets and pycrypto, I would strongly suggest you use Twisted with SSL instead.
setrofim
 
Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm

Re: pyCrypto for linux and windows

Postby newbi3 » Sun Apr 21, 2013 10:00 pm

Thanks I am looking into twisted right now!
newbi3
 
Posts: 2
Joined: Sun Apr 21, 2013 12:51 am


Return to General Coding Help

Who is online

Users browsing this forum: snippsat, W3C [Linkcheck] and 3 guests