📜  RC4算法的实现

📅  最后修改于: 2021-04-30 02:21:46             🧑  作者: Mango

RC4是一种对称流密码和可变密钥长度算法。该对称密钥算法被相同地用于加密和解密,因此数据流可以简单地与生成的密钥序列进行异或。该算法是串行的,因为它需要根据密钥序列进行状态条目的连续交换。该算法分为两个阶段:

密钥调度算法(KSA)

  • 通过使用由0256个字节组成的可变长度密钥应用置换来生成状态数组。
  • 状态向量被标识为S [0]S [1]…。 S [255]{0,1,2,…,255}初始化。密钥K [0]K [1],….,K [255]的长度可以从0256个字节,用于初始化置换S。每个K [I]和S [I]是一个字节。
  • 如果密钥的长度为256个字节,则K是一个临时数组,将其复制到K,否则在复制K的其余位置后,将重复的Key Value填充到K的剩余位置,直到充满为止。
S[] is permutation of 0, 1, ..., 255
key[] contains N bytes of key

for i = 0 to 255
    S[i] = i
    
    // Selects a keystream byte from
    // the table
    K[i] = key[i (mod N)]
    i++
j = 0

for i = 0 to 255
    j = (j + S[i] + K[i]) mod 256
    
    // Swaps elements in the current
    // lookup table
    swap(S[i], S[j])
i = j = 0

伪随机数生成算法(PRGA)用于在经过一轮置换后从状态向量数组生成密钥流字节。

Keystream Generation(i := 0, j := 0 )

while Generating Output:
    i = (i + 1) mod 256
    j = (j + S[i]) mod 256
    swap(S[i], S[j])
    t = (S[i] + S[j]) mod 256
    keystreamByte = S[t]

At each iteration, swap elements in table
and select keystream byte

然后,在生成的密钥流和用于加密的纯文本之间执行XOR。

请按照与上述相同的步骤进行解密,并在各处使用密文代替明文。

例子:

以下是上述方法的实现,并详细输出了涉及的所有重要步骤:

Python3
# Python3 program for the above approach
# of RC4 algorithm
  
# Function for encryption
def encryption():
  
    global key, plain_text, n
  
    # Given text and key
    plain_text = "001010010010"
    key = "101001000001"
  
    # n is the no: of bits to
    # be considered at a time
    n = 3
  
    print("Plain text : ", plain_text)
    print("Key : ", key)
    print("n : ", n)
  
    print(" ")
  
    # The initial state vector array
    S = [i for i in range(0, 2**n)]
    print("S : ", S)
  
    key_list = [key[i:i + n] for i in range(0, len(key), n)]
  
    # Convert to key_stream to decimal
    for i in range(len(key_list)):
        key_list[i] = int(key_list[i], 2)
  
    # Convert to plain_text to decimal
    global pt
  
    pt = [plain_text[i:i + n] for i in range(0, len(plain_text), n)]
  
    for i in range(len(pt)):
        pt[i] = int(pt[i], 2)
  
    print("Plain text ( in array form ): ", pt)
  
    # Making key_stream eqaul
    # to length of state vector
    diff = int(len(S)-len(key_list))
  
    if diff != 0:
        for i in range(0, diff):
            key_list.append(key_list[i])
  
    print("Key list : ", key_list)
    print(" ")
  
    # Perform the KSA algorithm
    def KSA():
        j = 0
        N = len(S)
          
        # Iterate over the range [0, N]
        for i in range(0, N):
            
            # Find the key
            j = (j + S[i]+key_list[i]) % N
              
            # Update S[i] and S[j]
            S[i], S[j] = S[j], S[i]
            print(i, " ", end ="")
              
            # Print S
            print(S)
  
        initial_permutation_array = S
          
        print(" ")
        print("The initial permutation array is : ",
              initial_permutation_array)
  
    print("KSA iterations : ")
    print(" ")
    KSA()
    print(" ")
  
    # Perform PGRA algorithm
    def PGRA():
  
        N = len(S)
        i = j = 0
        global key_stream
        key_stream = []
  
        # Iterate over [0, length of pt]
        for k in range(0, len(pt)):
            i = (i + 1) % N
            j = (j + S[i]) % N
              
            # Update S[i] and S[j]
            S[i], S[j] = S[j], S[i]
            print(k, " ", end ="")
            print(S)
            t = (S[i]+S[j]) % N
            key_stream.append(S[t])
  
        # Print the key stream
        print("Key stream : ", key_stream)
        print(" ")
  
    print("PGRA iterations : ")
    print(" ")
    PGRA()
  
    # Performing XOR between generated
    # key stream and plain text
    def XOR():
        global cipher_text
        cipher_text = []
        for i in range(len(pt)):
            c = key_stream[i] ^ pt[i]
            cipher_text.append(c)
  
    XOR()
  
    # Convert the encrypted text to
    # bits form
    encrypted_to_bits = ""
    for i in cipher_text:
        encrypted_to_bits += '0'*(n-len(bin(i)[2:]))+bin(i)[2:]
  
    print(" ")
    print("Cipher text : ", encrypted_to_bits)
  
  
encryption()
  
print("---------------------------------------------------------")
  
# Function for decryption of data
def decryption():
  
    # The initial state vector array
    S = [i for i in range(0, 2**n)]
  
    key_list = [key[i:i + n] for i in range(0, len(key), n)]
  
    # Convert to key_stream to decimal
    for i in range(len(key_list)):
        key_list[i] = int(key_list[i], 2)
  
    # Convert to plain_text to decimal
    global pt
  
    pt = [plain_text[i:i + n] for i in range(0, len(plain_text), n)]
  
    for i in range(len(pt)):
        pt[i] = int(pt[i], 2)
  
    # making key_stream eqaul
    # to length of state vector
    diff = int(len(S)-len(key_list))
  
    if diff != 0:
        for i in range(0, diff):
            key_list.append(key_list[i])
  
    print(" ")
  
    # KSA algorithm
    def KSA():
        j = 0
        N = len(S)
          
        # Iterate over the range [0, N]
        for i in range(0, N):
            j = (j + S[i]+key_list[i]) % N
              
            # Update S[i] and S[j]
            S[i], S[j] = S[j], S[i]
            print(i, " ", end ="")
            print(S)
  
        initial_permutation_array = S
        print(" ")
        print("The initial permutation array is : ",
              initial_permutation_array)
  
    print("KSA iterations : ")
    print(" ")
    KSA()
    print(" ")
  
    # Perform PRGA algorithm
    def do_PGRA():
  
        N = len(S)
        i = j = 0
        global key_stream
        key_stream = []
  
        # Iterate over the range
        for k in range(0, len(pt)):
            i = (i + 1) % N
            j = (j + S[i]) % N
              
            # Update S[i] and S[j]
            S[i], S[j] = S[j], S[i]
            print(k, " ", end ="")
            print(S)
            t = (S[i]+S[j]) % N
            key_stream.append(S[t])
  
    print("Key stream : ", key_stream)
    print(" ")
  
    print("PGRA iterations : ")
    print(" ")
    do_PGRA()
  
    # Perform XOR between generated
    # key stream  and cipher text
    def do_XOR():
        global original_text
        original_text = []
        for i in range(len(cipher_text)):
            p = key_stream[i] ^ cipher_text[i]
            original_text.append(p)
  
    do_XOR()
  
    # convert the decrypted text to
    # the bits form
    decrypted_to_bits = ""
    for i in original_text:
        decrypted_to_bits += '0'*(n-len(bin(i)[2:]))+bin(i)[2:]
  
    print(" ")
    print("Decrypted text : ",
          decrypted_to_bits)
  
# Driver Code
decryption()


输出:
Plain text :  001010010010
Key :  101001000001
n :  3
 
S :  [0, 1, 2, 3, 4, 5, 6, 7]
Plain text ( in array form ):  [1, 2, 2, 2]
Key list :  [5, 1, 0, 1, 5, 1, 0, 1]
 
KSA iterations : 
 
0  [5, 1, 2, 3, 4, 0, 6, 7]
1  [5, 7, 2, 3, 4, 0, 6, 1]
2  [5, 2, 7, 3, 4, 0, 6, 1]
3  [5, 2, 7, 0, 4, 3, 6, 1]
4  [5, 2, 7, 0, 6, 3, 4, 1]
5  [5, 2, 3, 0, 6, 7, 4, 1]
6  [5, 2, 3, 0, 6, 7, 4, 1]
7  [1, 2, 3, 0, 6, 7, 4, 5]
 
The initial permutation array is :  [1, 2, 3, 0, 6, 7, 4, 5]
 
PGRA iterations : 
 
0  [1, 3, 2, 0, 6, 7, 4, 5]
1  [1, 3, 6, 0, 2, 7, 4, 5]
2  [1, 3, 6, 2, 0, 7, 4, 5]
3  [1, 3, 6, 2, 0, 7, 4, 5]
Key stream :  [7, 1, 6, 1]
 
 
Cipher text :  110011100011
---------------------------------------------------------
 
KSA iterations : 
 
0  [5, 1, 2, 3, 4, 0, 6, 7]
1  [5, 7, 2, 3, 4, 0, 6, 1]
2  [5, 2, 7, 3, 4, 0, 6, 1]
3  [5, 2, 7, 0, 4, 3, 6, 1]
4  [5, 2, 7, 0, 6, 3, 4, 1]
5  [5, 2, 3, 0, 6, 7, 4, 1]
6  [5, 2, 3, 0, 6, 7, 4, 1]
7  [1, 2, 3, 0, 6, 7, 4, 5]
 
The initial permutation array is :  [1, 2, 3, 0, 6, 7, 4, 5]
 
Key stream :  [7, 1, 6, 1]
 
PGRA iterations : 
 
0  [1, 3, 2, 0, 6, 7, 4, 5]
1  [1, 3, 6, 0, 2, 7, 4, 5]
2  [1, 3, 6, 2, 0, 7, 4, 5]
3  [1, 3, 6, 2, 0, 7, 4, 5]
 
Decrypted text :  001010010010