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 doj = (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 256j=(j+S[i])mod 256Swap(S[i],S[j]);t=(S[i]+S[j])mod256;K[r]=S[t];
经过上述步骤后,得到和明文长度相同的密钥流
import base64def rc4_setup(key):"""RC4初始化"""if isinstance(key, str):key = key.encode()S = list(range(256))j = 0for i in range(256):j = (j + S[i] + key[i % len(key)]) % 256S[i], S[j] = S[j], S[i]return Sdef rc4_crypt(data, key):"""RC4加解密"""if isinstance(data, str):data = data.encode()S = rc4_setup(key)i, j = 0, 0res = []for byte in data:i = (i + 1) % 256j = (j + S[i]) % 256S[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博客