LewisFletch
LewisFletch

Reputation: 125

RC4 Encryption in Python

i've had a look through several python scripts for using an RC4 block cipher... i'm having issues completing the program so that it outputs properly...

Program currently asks for a "key" and "plaintext" (text to encrypt with key). and outputs a encoded string... i think. so if i enter the word "Plaintext" to encrypt i get the following. however i think this is incomplete...

[187, 243, 22, 232, 217, 64, 175, 10, 211]

i want to have my encrypted output in hex

BB F3 16 E8 D9 40 AF 0A D3

my program is incomplete at the moment, but would just like some direction on how to

  1. finish off the encryption part so it outputs as Hexadecimal (i think i have to convert bytes to hex?)

EDIT: The above has been resolved by Ebrahim. just need help with the decryption

  1. i'm lost on where to begin with the decryption... i want to be able to have an input that will take a key and a ciphertext both in hexadecimal; and decrypt the ciphertext to plaintext.

I understand the logic in the encryption process, but i'm having trouble grasping the decryption process even though it is quite similar.


# Global variables
state = [None] * 256
p = q = None

def setKey(key):
    ##RC4 Key Scheduling Algorithm
    global p, q, state
    state = [n for n in range(256)]
    p = q = j = 0
    for i in range(256):
        if len(key) > 0:
            j = (j + state[i] + key[i % len(key)]) % 256
        else:
        j = (j + state[i]) % 256
    state[i], state[j] = state[j], state[i]

def byteGenerator():
    ##RC4 Pseudo-Random Generation Algorithm
    global p, q, state
    p = (p + 1) % 256
    q = (q + state[p]) % 256
    state[p], state[q] = state[q], state[p]
    return state[(state[p] + state[q]) % 256]

def encrypt(key,inputString):
    ##Encrypt input string returning a byte list
    setKey(string_to_list(key))
    return [ord(p) ^ byteGenerator() for p in inputString]

def decrypt(inputByteList):
    ##Decrypt input byte list returning a string
    return "".join([chr(c ^ byteGenerator()) for c in inputByteList])



def intToList(inputNumber):
    ##Convert a number into a byte list
    inputString = "{:02x}".format(inputNumber)
    return [int(inputString[i:i + 2], 16) for i in range(0,    len(inputString), 2)]

def string_to_list(inputString):
    ##Convert a string into a byte list
    return [ord(c) for c in inputString]




loop = 1
while loop == 1: #simple loop to always bring the user back to the menu

    print("RC4 Encryptor/Decryptor")
    print
    print("Please choose an option from the below menu")
    print
    print("1) Encrypt")
    print("2) Decrypt")
    print

    choice = input("Choose your option: ")
    choice = int(choice)

    if choice == 1:
        key = raw_input("Enter Key: ")
        inputstring = raw_input("enter plaintext: ")
        encrypt(key, inputstring)


    elif choice == 2:   
        key = raw_input("Enter Key: ")
        ciphertext = raw_input("enter plaintext: ")
        print decrypt(intToList(ciphertext))

    elif choice == 3: 
    #returns the user to the previous menu by ending the loop and clearing the screen.
        loop = 0

    else:   
        print ("please enter a valid option") #if any NUMBER other than 1, 2 or 3 is entered.

Upvotes: 1

Views: 13296

Answers (2)

Darian Lopez Utra
Darian Lopez Utra

Reputation: 83

I know this is very old question, but here are some insigths just in case:

  • First RC4 is not a block cipher, is a stream cipher
  • Second, the decryption is exact the same as the encryption, as the algorithm generates the ciphertext by XORing the plaintext with some stream obtained using the key, and XOR is reversible, meaning: to decypher just need to XOR the ciphertext with the same generated stream.

Upvotes: 0

EbraHim
EbraHim

Reputation: 2359

To convert your decimal output to hex output:

>>> arr = [187, 243, 22, 232, 217, 64, 175, 10, 211]
>>> ' '.join('%02x'%i for i in arr)
'bb f3 16 e8 d9 40 af 0a d3'
>>> 

Upvotes: 1

Related Questions