Реализация алгоритма RC4

Опубликовано: 23 Декабря, 2021

RC4 - это алгоритм симметричного потокового шифра и переменной длины ключа. Этот алгоритм с симметричным ключом идентично используется для шифрования и дешифрования, так что поток данных просто подвергается операции XOR с сгенерированной последовательностью ключей. Алгоритм является последовательным, поскольку требует последовательных обменов записями состояния на основе ключевой последовательности. Алгоритм работает в два этапа:

Ключевой алгоритм планирования (KSA) :

  • Он используется для генерации массива состояний путем применения перестановки с использованием ключа переменной длины, состоящего от 0 до 256 байтов .
  • Вектор состояния обозначается как S [0] , S [1]…. S [255] инициализируется с помощью {0, 1, 2,…, 255} . Ключ K [0] , K [1],…., K [255] может иметь любую длину от 0 до 256 байтов и используется для инициализации перестановки S. Каждый K [I] и S [I] является байтом. .
  • K является временным массивом, если длина ключа составляет 256 байт, скопируйте его в K, иначе после копирования оставшиеся позиции K будут заполнены повторяющимися значениями ключа до полного заполнения.
 S [] - это перестановка 0, 1, ..., 255
key [] содержит N байтов ключа

для i = от 0 до 255
    S [i] = i
    
    // Выбирает байт ключевого потока из
    // стол
    K [i] = ключ [i (mod N)]
    я ++
j = 0

для i = от 0 до 255
    j = (j + S [i] + K [i]) mod 256
    
    // Меняем местами элементы в текущем
    // Справочная таблица
    своп (S [i], S [j])
я = j = 0

Алгоритм псевдослучайной генерации (PRGA) : он используется для генерации байта ключевого потока из массива векторов состояний после еще одного раунда перестановки.

 Генерация ключевого потока (i: = 0, j: = 0)

при генерации вывода:
    я = (я + 1) по модулю 256
    j = (j + S [i]) mod 256
    своп (S [i], S [j])
    t = (S [i] + S [j]) mod 256
    keystreamByte = S [t]

На каждой итерации меняйте местами элементы в таблице
и выберите байт ключевого потока

Затем выполните операцию XOR между сгенерированным потоком ключей и простым текстом для шифрования.

Выполните ту же процедуру, что и выше, для расшифровки, везде беря зашифрованный текст вместо обычного текста.

Примеры:

Input: plain text = 001010010010, key = 101001000001, n= 3
Output: 
cipher text = 110011100011
decrypted text = 001010010010

Input: plain text = 1111000000001111, key = 0101010111001010, n= 4
Output:
cipher text = 0011011110100010
decrypted text = 1111000000001111

Ниже представлена реализация описанного выше подхода с подробным выводом всех важных этапов:

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()
Выход:
Обычный текст: 001010010010
Ключ: 101001000001
п: 3
 
S: [0, 1, 2, 3, 4, 5, 6, 7]
Обычный текст (в виде массива): [1, 2, 2, 2]
Список ключей: [5, 1, 0, 1, 5, 1, 0, 1]
 
Итерации KSA: 
 
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]
 
Исходный массив перестановок: [1, 2, 3, 0, 6, 7, 4, 5]
 
Итерации PGRA: 
 
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]
Ключевой поток: [7, 1, 6, 1]
 
 
Шифрованный текст: 110011100011
-------------------------------------------------- -------
 
Итерации KSA: 
 
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]
 
Исходный массив перестановок: [1, 2, 3, 0, 6, 7, 4, 5]
 
Ключевой поток: [7, 1, 6, 1]
 
Итерации PGRA: 
 
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]
 
Расшифрованный текст: 001010010010

Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по доступной для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .

Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.