RC4原理以及python實現
阿新 • • 發佈:2018-12-23
簡介
RC4(來自Rivest Cipher 4的縮寫)是一種流加密演算法,金鑰長度可變。它加解密使用相同的金鑰,一個位元組一個位元組
地加密。因此也屬於對稱加密演算法。突出優點是在軟體裡面很容易實現。
加密流程
包含兩個處理過程:一是祕鑰排程演算法(KSA),用於之亂S盒的初始排列,另外一個是偽隨機數生成演算法(PRGA),用來輸出隨機序列並修改S的當前順序。
- 根據祕鑰生成S盒
- 利用PRGA生成祕鑰流
- 祕鑰與明文異或產生密文
單個點拿出來分析
根據祕鑰生成S盒
初始化S盒
直接構造一個S[256],遍歷0255,然後建立臨時T[256],用於儲存種子祕鑰,長度不夠迴圈填充直到T被填滿,根據T[i]將S[i]與S中的另外一個位元組對換,對S的操作僅僅是交換,唯一改變的是位置,但裡面的元素是沒變的還是0
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]
#print(type(s_box)) #for_test
return s_box
下圖很好的解釋了S盒被隨機化的過程
利用PRGA生成祕鑰流
從S盒選取一個元素輸出,並置換S盒便於下一輪取出,選取過程取決於索引i和j,這也體現了在加密過程中S盒會變化。下面的是流程:
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)) #直接與每一個位元組明文相異或
祕鑰與明文異或產生密文
至於這一點就不用多說了,由於異或運算的對合性,RC4加密解密使用同一套演算法。
python實現:
# -*- coding: utf-8 -*-
# Author:0verWatch
import base64
def get_message():
print("輸入你的資訊:")
s = input()
return s
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]
#print(type(s_box)) #for_test
return s_box
def ex_encrypt(plain,box,mode):
"""
利用PRGA生成祕鑰流並與密文位元組異或,加解密同一個演算法
"""
if mode == '2':
while True:
c_mode = input("輸入你的解密模式:Base64 or ordinary\n")
if c_mode == 'Base64':
plain = base64.b64decode(plain)
plain = bytes.decode(plain)
break
elif c_mode == 'ordinary':
plain = plain
break
else:
print("Something Wrong,請重新新輸入")
continue
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)
#print(cipher)
if mode == '1':
# 化成可視字元需要編碼
print("加密後的輸出(沒經過任何編碼):")
print(cipher)
# base64的目的也是為了變成可見字元
print("base64後的編碼:")
print(str(base64.b64encode(cipher.encode('utf-8')),'utf-8'))
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_message()
key = get_key()
box = init_box(key)
ex_encrypt(message, box, mode)
else:
print("輸入有誤!")
if __name__ == '__main__':
while True:
get_mode()
安全性
- 由於RC4演算法加密是採用的xor,所以,一旦子金鑰序列出現了重複,密文就有可能被破解。所以必須對加密金鑰進行測試,判斷其是否為弱金鑰。
- 當然,現在RC4已經不安全了,可以參考這篇文章,破解RC4現在是具有很高效率的。