RC4算法由Ron rivest于1987年设计出的一种对称加密
算法,其加密密钥和解密密钥是相同的,加密和解密过程也相同。
属于对称加密算法中的流密码
加密算法,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密。密钥长度可变
,面向字节操作。是以一个足够大的表s为基础,对表进行非线性变换,产生密钥流。
1、对S表
进行线性填充(一般为256
字节,用来作为密钥流生成的种子1)
2、用种子密钥(就是我们的秘钥)
循环填充另一个256字节的K表
,(用来作为密钥流生成的种子2)
如果输入长度大于等于256个字节,则进行截取
如果输入长度小于256个字节,则进行轮转,直到填满
例如输入密钥的是1,2,3,4,5 , 那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5........
3、用K表
对S表
进行初始置换(用来打乱初始种子1)
按照下列规则进行
//从第零个字节开始,执行256次,保证每个字节都得到处理
j = 0;
for i=0 to 255 do
j = (j+S[i]+K[i])mod 256;
Swap(S[i],S[j]);
i,j = 0;
for r=0 to len do // len为明文长度,len字节
i=(i+1)mod 256
j=(j+S[i])mod 256
Swap(S[i],S[j]);
t=(S[i]+S[j])mod256;
K[r]=S[t];
经过上述步骤后,得到和明文长度相同的密钥流
import base64
def rc4_setup(key):
"""RC4初始化"""
if isinstance(key, str):
key = key.encode()
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
return S
def rc4_crypt(data, key):
"""RC4加解密"""
if isinstance(data, str):
data = data.encode()
S = rc4_setup(key)
i, j = 0, 0
res = []
for byte in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
res.append(byte ^ S[(S[i] + S[j]) % 256])
return bytes(res)
def rc4_encrypt(data, key):
"""RC4加密"""
return rc4_crypt(data, key)
def rc4_decrypt(data, key):
"""RC4解密"""
return rc4_crypt(data, key)
def rc4_hex(key_hex, data_hex):
"""RC4加解密(16进制)"""
key = bytes.fromhex(key_hex)
data = bytes.fromhex(data_hex)
res = rc4_crypt(data, key)
return res.hex()
def rc4_encrypt_base64(data, key):
"""RC4加密并转换为base64格式"""
encrypted_data = rc4_encrypt(data, key)
return base64.b64encode(encrypted_data).decode()
def rc4_decrypt_base64(data, key):
"""base64格式解码后RC4解密"""
encrypted_data = base64.b64decode(data)
return rc4_decrypt(encrypted_data, key).decode()
if __name__ == '__main__':
plaintext = b'Thisismessage'
key = b'password123'
# RC4加密
ciphertext = rc4_encrypt(plaintext, key)
print("RC4加密", ciphertext)
# RC4解密
decrypted_text = rc4_decrypt(ciphertext, key)
print("RC4解密", decrypted_text)
# 16进制数据的RC4加解密
ciphertext_hex = rc4_hex(key.hex(), plaintext.hex())
print("16进制数据的RC4加密:", ciphertext_hex)
decrypted_text_hex = rc4_hex(key.hex(), ciphertext_hex)
print("16进制数据的RC4解密:", decrypted_text_hex)
# base64数据的RC4加解密
ciphertext_base64 = rc4_encrypt_base64(plaintext, key)
print("base64数据的RC4加密:", ciphertext_base64)
decrypted_text_base64 = rc4_decrypt_base64(ciphertext_base64, key)
print("base64数据的RC4解密:", decrypted_text_base64)
import java.util.Base64;
public class RC4 {
private int[] S = new int[256];
private int[] T = new int[256];
private void ksa(byte[] key) {
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % key.length];
}
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
swap(i, j);
}
}
private void swap(int i, int j) {
int temp = S[i];
S[i] = S[j];
S[j] = temp;
}
public byte[] encrypt(byte[] plaintext, byte[] key) {
ksa(key);
int i = 0, j = 0;
byte[] ciphertext = new byte[plaintext.length];
for (int k = 0; k < plaintext.length; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(i, j);
int t = (S[i] + S[j]) % 256;
ciphertext[k] = (byte) (plaintext[k] ^ S[t]);
}
return ciphertext;
}
public byte[] decrypt(byte[] ciphertext, byte[] key) {
return encrypt(ciphertext, key);
}
public String encryptToBase64(String plaintext, String key) {
byte[] bytes = encrypt(plaintext.getBytes(), key.getBytes());
return Base64.getEncoder().encodeToString(bytes);
}
public String decryptFromBase64(String ciphertext, String key) {
byte[] bytes = Base64.getDecoder().decode(ciphertext);
byte[] decrypted = decrypt(bytes, key.getBytes());
return new String(decrypted);
}
public String encryptToHex(String plaintext, String key) {
byte[] bytes = encrypt(plaintext.getBytes(), key.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public String decryptFromHex(String ciphertext, String key) {
byte[] bytes = new byte[ciphertext.length() / 2];
for (int i = 0; i < ciphertext.length(); i += 2) {
bytes[i / 2] = (byte) Integer.parseInt(ciphertext.substring(i, i + 2), 16);
}
byte[] decrypted = decrypt(bytes, key.getBytes());
return new String(decrypted);
}
public static void main(String[] args) {
RC4 rc4 = new RC4();
String plaintext = "Thisismessage";
String key = "password123";
//16进制数据的RC4加解密
String ciphertext_hex = rc4.encryptToHex(plaintext, key);
System.out.println("16进制数据的RC4加密:" + ciphertext_hex);
//16进制数据的RC4解密
String decrypted_text_hex = rc4.decryptFromHex(ciphertext_hex, key);
System.out.println("16进制数据的RC4解密:" + decrypted_text_hex);
//base64数据的RC4加密
String ciphertext_base64 = rc4.encryptToBase64(plaintext, key);
System.out.println("base64数据的RC4加密:" + ciphertext_base64);
//base64数据的RC4解密
String decrypted_text_base64 = rc4.decryptFromBase64(ciphertext_base64, key);
System.out.println("base64数据的RC4解密:" + decrypted_text_base64);
}
}
CryptoJS库生成的RC4加密值每次不同是因为它使用了一个称为“随机盐”
的概念。这个随机盐是根据随机值
和固定值4294967296
生成的,在每个加密操作中都是不同的。盐的目的是确保每个加密结果都是不同的,即使输入相同。
random: function(c) {
for (var a = [], m = 0; m < c; m += 4)
a.push(4294967296 * s.random() | 0);
return new d.init(a,c)
}
在使用随机盐时,它是作为加密过程的一部分引入的。使用随机盐的过程是RC4加密的第一步——密钥调度算法。
密钥调度算法是一个基于密钥的伪随机数生成器,用于生成 RC4 加密中使用的密钥流。在这个算法中,随机盐值被添加到给定的密钥中,以创建更随机的、更安全的密钥流,进而提高加密安全性。
具体而言,密钥调度算法会将随机盐值添加到密钥中,然后将调度算法的状态初始化为一个固定的矢量(通常是一个全0的数组)。然后,该算法会执行一些循环迭代,使用密钥和矢量来创建一个伪随机的密钥流。
在 RC4 加密的实际加密过程中,该密钥流和明文进行异或运算来生成加密结果。因此,随机盐值是生成 RC4 加密结果的关键组成部分。
在安卓逆向中,RC4的特征并没有Base64那么明显,但是也可以根据S表的长度、密钥流的产生过程及异或运算的特征来确定是否是RC4,当然,因为RC4属于流加密,所以也可以把明文的长度和加密后的长度是否相等
作为入手点。
(41条消息) 密码学 | 对称加密算法RC4_rc4加密算法_FalsePlus的博客-CSDN博客