1.RC4算法简介
RC4算法由Ron rivest于1987年设计出的一种对称加密算法,其加密密钥和解密密钥是相同的,加密和解密过程也相同。RC4算法是属于对称密码算法中的面向字节操作的序列密码(streamcipher,又称为流密码),其密钥长度可变。与分组加密算法不同的是,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密。
RC4算法加密流程主要包括密钥调度算法KSA和伪随机子密码生成算法PRGA两部分。其主要的流程如下:
(1)KSA密钥调度算法(初始化S表):
a.对S表进行线性填充,一般为256个字节;
b.用种子密钥填充另一个256字节对K表;(如果种子密钥长度小于256,就循环进行填充)
c.用K表对S表进行初始置换,置换规则如下:
i=0;j=0;
j=( j+S[i]+K[i] )mod256;
Swap(S[i],S[j])
(2)密钥流生成算法(为每个待加密的字节生成一个伪随机数,用来和明文进行异或,从而进行加密)生成规则如下:
i = (i+1)%256;
j=(j+S[i])%256;
swap(S[i],S[j]);
t=(S[i]+S[j])%256;
k[r]=S[t]
2.Java实现RC4算法
import java.util.Random;
import java.util.Scanner;
public class RC4Demo {
public static void main(String[] args) {
// 输入明文
System.out.println("请输入明文:");
Scanner sc = new Scanner(System.in);
String plainText = sc.nextLine();
// 获取随机密钥
System.out.println("请输入密钥长度:");
int keylen = sc.nextInt();
String key = getKey(keylen);
System.out.println("随机密钥是:" + key);
// 进行加密和解密并打印
String cipher = Encrypt(plainText, key);
String plainer = Encrypt(cipher, key);
System.out.println("'" + plainText + "'" + "加密后密文是:" + cipher);
System.out.println("'" + cipher + "'" + "解密后明文是:" + plainer);
}
// 随机密钥方法
public static String getKey(int keylen) {
char[] k = new char[keylen];
Random r = new Random();
for (int i = 0; i < keylen; i++) {
k[i] = (char) ('a' + r.nextInt() % 26);
}
String s = new String(k);
return s;
}
// 加密方法
public static String Encrypt(String plainText, String key) {
// 1.1 初始化一个S表和一个K表
int[] S = new int[256];
byte[] K = new byte[256];
// 初始化一个密钥流
Character[] keySchedul = new Character[plainText.length()];
// 1.2 调用KSA方法对S表进行初始排列
KSA(S, K, key);
// 1.3 调用RPGA方法产生密钥流
RPGA(S, keySchedul, plainText.length());
// 存放密文结果
StringBuffer cipherResult = new StringBuffer();
// 进行加密--用明文和密钥流进行异或操作
for (int i = 0; i < plainText.length(); i++) {
cipherResult.append((char) (plainText.charAt(i) ^ keySchedul[i]));
}
return cipherResult.toString();
}
// RSA密钥调度算法---实现用K表对S表的置换
public static void KSA(int[] S, byte[] K, String key) {
// 对S表进行初始赋值
for (int i = 0; i < 256; i++) {
S[i] = i;
}
// 用种子密钥对K表进行填充
for (int i = 0; i < 256; i++) {
K[i] = (byte) key.charAt((i % key.length()));
}
// 对S表进行置换
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + K[i]) % 256;
swap(S, i, j);
}
}
// RPGA--伪随机生成算法--利用上面重新排列的S盒来产生任意长度的密钥流
public static void PRGA(int[] S, Character[] keySchedul, int plainTextLen) {
int i = 0, j = 0;
for (int k = 0; k < plainTextLen; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(S, i, j);
keySchedul[k] = (char) (S[(S[i] + S[j]) % 256]);
}
}
// 交换方法,实现交换两个位置的元素
public static void swap(int[] S, int i, int j) {
int temp = S[i];
S[i] = S[j];
S[j] = temp;
}
}