RC4 decryption in python hexadecimal inputs

时间:2016-04-25 09:13:28

标签: python cryptography

I have a program that successfully encrypts a piece of plain text information and outputs the encrypted data as hexadecimal. i can decrypt this data on http://www.fyneworks.com/encryption/rc4-encryption/index.asp by putting in the hex data i received from my program and the key i used (in plain text)

the next step i am trying to accomplish is to have two inputs where i can input an encrypted message in hex and the encryption key (also in hex).

i'm having trouble getting the decryption part of my program to work...

If i enter the key as password and the ciphertext as 8c905b7c294a94c30422d81d552e which successfully decrypts on the website above... it doesn't work.

anyone have any ideas how i can get decryption working in RC4 with hexadecimal inputs?

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

def setKey(key):
   ##RC4 Key Scheduling Algorithm (KSA)
    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 (PRGA)
    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]

key = raw_input("Enter Key: ")
ciphertext = raw_input("enter ciphertext: ")
print decrypt(intToList(ciphertext))

1 个答案:

答案 0 :(得分:1)

以下是使用reference implementation RC4 for python进行加密/解密的一般概念:

def KSA(key):
    keylength = len(key)

    S = range(256)

    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % keylength]) % 256
        S[i], S[j] = S[j], S[i]  # swap

    return S


def PRGA(S):
    i = 0
    j = 0
    while True:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]  # swap

        K = S[(S[i] + S[j]) % 256]
        yield K


def RC4(key):
    S = KSA(key)
    return PRGA(S)


if __name__ == '__main__':

    # ciphertext should be 9D5AB375EC
    key = 'secret'
    plaintext = 'plain'

    def convert_key(s):
        return [ord(c) for c in s]
    key = convert_key(key)

    keystream = RC4(key)

    ciphertext = ''.join([("%02X" % (ord(c) ^ keystream.next())) for c in plaintext])
    print ciphertext

    keystream = RC4(key)

    def convert_ct(s):
        import binascii
        return [ord(ch) for ch in binascii.unhexlify(s)]

    ciphertext = convert_ct(ciphertext)

    plaintext = ''.join([chr(c ^ keystream.next()) for c in ciphertext])
    print plaintext

使用您的代码库可以这样完成:

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

def setKey(key):
    ##RC4 Key Scheduling Algorithm (KSA)
    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 (PRGA)
    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, plaintext):
    ##Encrypt input string returning a byte list
    pt = string_to_list(plaintext)
    ct = rc4(key, pt)
    return list_to_string(ct, hex=True)

def decrypt(key, ciphertext):
    ##Decrypt input byte list returning a string
    ct = string_to_list(ciphertext, hex=True)
    pt = rc4(key, ct)
    return list_to_string(pt, hex=False)

def string_to_list(input_srt, hex=False):
    ##Convert a string into an int list
    if hex:
        res = [ord(ch) for ch in binascii.unhexlify(input_srt)]
    else:
        res = [ord(ch) for ch in input_srt]
    return res

def list_to_string(lst, hex=True):
    ##Convert an int list into a string
    if hex:
        res = ''.join(["%0.2X" % el for el in lst])
    else:
        res = ''.join([chr(el) for el in lst])
    return res

def rc4(key, ints):
    """Xor list of ints with output generated by RC4. Output list of ints"""
    setKey(string_to_list(key))
    return [x ^ byteGenerator() for x in ints]

# key = raw_input("Enter Key: ")
# ciphertext = raw_input("enter ciphertext: ")
key = 'secret'
plaintext = 'plain'

ciphertext = encrypt(key, plaintext)
print ciphertext
print decrypt(key, ciphertext)

解密和加密基本上是相同的程序