RC4算法是一种对称加密算法,即加密与解密的过程相同。假设其运算过程表示为rc4(key, data),其中key为密钥,data为待处理的数据,则:
密文=rc4(key,data) data=rc4(key,密文)也就是说,对一段数据(原文)做奇数次RC4运算,得到密文,做偶数次RC4运算,结果还是原文。
RC4算法是基于密钥流的加密算法。 假设要加密的数据(明文)长度为N个字节,通过某种算法产生N字节的数据(密钥),将这两串数据按位异或(XOR),得到密文。把密文与这串密钥再XOR,就能得到明文。这一串由某种算法产生的N字节(8N位),称为密钥流,对应算法就叫做密钥流生成算法。区分不同基于密钥流的加密算法的标准就是其密钥流的生成方式。
算法特点: 简单,运行速度快,密钥长度可变(长度范围为 1-256 字节)。
RC4算法组成:
1、S盒生成 根据用户输入的秘钥 key,使用 密钥调度算法(key-scheduling algorithm,KSA)生成 S 盒。
2、生成密钥流,加密数据 使用伪随机生成算法(Pseudo-random generation algorithm,PRGA)生成秘钥流,然后使用生成的密钥流加密明文数据,得到密文。
对应得到的密文,可以根据需要再做处理,例如base64编码。
这里需要注意的是,对于包含中文的明文,需要做适当的编码(encode)和解码(decode)处理,编码方法一般为“utf-8”,同时还涉及字符转ascii编码(10进制)等操作。
可以通过导入Crypto.Cipher中的ARC4来实现,也可以自定义实现,本文通过自定义方法实现。
代码运行环境: windows 10 python 3.7
# coding=utf-8 # python 3.7 import sys def bytesToHex(bytes): sb = '' for i in range(len(bytes)): hexs = hex(bytes[i] & 0xFF)[2:] if len(hexs) < 2: sb += '0' sb += hexs return sb def hexToByte(inHex): hexlen = len(inHex) result = [] if (hexlen % 2 == 1): hexlen += 1 inHex="0"+inHex for i in range(0, hexlen, 2): result.append(int(inHex[i:i+2],16)) return result def initKey(aKey): state = list(range(256)) bkey =[ord(i) for i in list(aKey)] index1 = 0 index2 = 0 if (len(bkey) == 0): return [] for i in range(256): index2 = ((bkey[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff state[i], state[index2] = state[index2], state[i] index1 = (index1 + 1) % len(bkey) return state def RC4Base(input, mKkey): x = 0 y = 0 key = initKey(mKkey) result = list(range(len(input))) for i in range(len(input)): x = (x + 1) & 0xff y = ((key[x] & 0xff) + y) & 0xff key[x], key[y] = key[y], key[x] xorIndex = ((key[x] & 0xff) + (key[y] & 0xff)) & 0xff result[i] = (input[i] ^ key[xorIndex]) return result def encryRC4Byte(data, key, chartSet='utf-8'): if not chartSet: bData = [ord(i) for i in data] return RC4Base(bData, key) else: bData = list(data.encode(chartSet)) return RC4Base(bData, key) def decryRC4(data, key, chartSet='utf-8'): r = RC4Base(hexToByte(data), key) return bytes(r).decode(chartSet) def encryRC4String(data, key, chartSet='utf-8'): return bytesToHex(encryRC4Byte(data, key, chartSet)) def main(data, key, signs): if signs == 'encode': datas = encryRC4String(data, key) else: datas = decryRC4(data, key) print(datas) if __name__ =='__main__': try: key = sys.argv[2] #"key" data = sys.argv[1] #"encoded_string" choices=sys.argv[3].strip() # decode or encode if choices not in ['decode', 'encode']: print('usage: %s string2decode key_string decode' % sys.argv[0]) print(' or: %s string2encode key_string encode' % sys.argv[0]) exit() except: print('usage: %s string2decode key_string decode' % sys.argv[0]) print(' or: %s string2encode key_string encode' % sys.argv[0]) exit() main(data,key,choices)使用方法很简单,需要的参数共3个,第一个data参数为明文或密文,第二个参数key为密钥,第三个choices为加密(encode)或者解密(deocde)操作,假设代码保存为rc4.py文件,在命令行中执行:
python rc4.py dsadasMI明文 thisiskey encode得到密文:efc3c7d2cb1ffc0b1fd84d6f000b 。
进行解密:
python rc4.py efc3c7d2cb1ffc0b1fd84d6f000b thisiskey decode得到明文: dsadasMI明文 。
