python学习之RC4算法实现

RC4算法

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明文 。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值