欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RC4算法python编程实现

程序员文章站 2022-07-09 10:19:32
...

RC4于1987年提出,和DES算法一样。是一种对称加密算法,也就是说使用的**为单钥(或称为私钥)。

但不同于DES的是。RC4不是对明文进行分组处理,而是字节流的方式依次加密明文中的每个字节。解密的时候也是依次对密文中的每个字节进行解密。

RC4算法的特点是算法简单,执行速度快。并且**长度是可变的,可变范围为1-256字节(8-2048比特),在现在技术支持的前提下,当**长度为128比特时,用暴力法搜索**已经不太可行,所以能够预见RC4的**范围任然能够在今后相当长的时间里抵御暴力搜索**的攻击。实际上,现在也没有找到对于128bit**长度的RC4加密算法的有效攻击方法。

RC4算法:RC4是一种对称密码算法,它属于对称密码算法中的序列密码(streamcipher,也称为流密码),它是可变**长度,面向字节操作的流密码。

RC4算法中的关键变量:

1、**流:RC4算法的关键是依据明文和**生成相应的**流,**流的长度和明文的长度是相应的。也就是说明文的长度是500字节,那么**流也是500字节。当然,加密生成的密文也是500字节。由于密文第i字节=明文第i字节^**流第i字节

 

2、状态向量S:长度为256。S[0],S[1].....S[255]。每一个单元都是一个字节。算法执行的不论什么时候。S都包含0-255的8比特数的排列组合,仅仅只是值的位置发生了变换;

 

3、暂时向量T:长度也为256,每一个单元也是一个字节。假设**的长度是256字节。就直接把**的值赋给T,否则,轮转地将**的每一个字节赋给T。

 

4、**K:长度为1-256字节。注意**的长度keylen与明文长度、**流的长度没有必定关系。通常**的长度趣味16字节(128比特)。

 

RC4算法加密流程:

包括**调度算法KSA和伪随机子密码生成算法PRGA两大部分(以**长度为256个字节为例)。

**调度算法:首先初始化状态矢量S,矢量S中元素的值被按升序从0到255排列,即S[0]=00, S[1]=1, …, S[255]=255.同时建立一个临时矢量T,如果**K的长度为256字节,则将K赋给T。否则,若**长度为keylen字节,则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。

RC4的原理分为三步:

1、初始化S和T

for i=0 to 255 do

S[i] =i;

T[i]=K[ I mod keylen ];

2、初始排列S

for i=0 to 255 do

j= ( j+S[i]+T[i])mod256;

swap(S[i],S[j]);

3、产生**流

for r=0 to len do 

i=(i+1) mod 256;

j=(j+S[i])mod 256;

swap(S[i],S[j]);

t=(S[i]+S[j])mod 256;

k[r]=S[t];

 

代码实现 

cipher1=""
def get_message():
    fo = open("data.txt","r")
    s = fo.read()
    s=str(s)
    fo.close()
    return s
def get_message1():
    return cipher1
def get_key():
    print("输入你的秘钥:")
    key = input()
    if key == '':
        key = 'none_public_key'
    return key
def init_box(key):
    """
    S盒 
    """
    s_box = list(range(256)) #这里没管秘钥小于256的情况,小于256应该不断重复填充即可
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    return s_box
def ex_encrypt(plain,box,mode):
    """
    利用PRGA生成秘钥流并与密文字节异或,加解密同一个算法
    """
    if mode == '2':
        plain = plain
    res = []
    i = j =0
    for s in plain:
        i = (i + 1) %256
        j = (j + box[i]) %256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j])% 256
        k = box[t]
        res.append(chr(ord(s)^k))
    cipher = "".join(res)
    if  mode == '1':
        fo=open("cipher.txt","wb+")
        # 化成可视字符需要编码
        print("加密后的输出:")
        print(cipher)
        #print(type(cipher))
        global cipher1
        cipher1 = cipher
        cipher = cipher.encode()
        fo.seek(0)
        fo.write(cipher)
        fo.seek(0)
        listsss=[fo.read(1) for i in range(100)]
        fo.close()
    if mode == '2':
        # 化成可视字符需要编码
        print("解密后的输出:")
        print(cipher)
def get_mode():
    print("请选择加密或者解密")
    print("1. Encrypt")
    print("2. Decode")
    mode = input()
    if mode == '1':
        message = get_message()
        key = get_key()
        box = init_box(key)
        ex_encrypt(message,box,mode)
    elif mode == '2':
        message = get_message1()
        key = get_key()
        box = init_box(key)
        ex_encrypt(message, box, mode)
    else:
        print("输入有误!")
if __name__ == '__main__':
    while True:
        get_mode()