Rc4的加密和解密
2019-11-10 本文已影响0人
麦田夕阳
Rc4:
在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。
Rc4加密的原理:
主要包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)两大部分。假设S-box的长度为256,密钥长度为Len
在初始化的过程中,密钥的主要功能是将S-box搅乱,i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。而不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,将S-box和明文进行xor运算,得到密文,解密过程也完全相同。
1.初始化秘钥:根据输入的秘钥key,使用密钥调度算法(KSA)生成一个256字节的sbox。
2.再通过伪随机数生成算法(PRGA)得到密钥流(keystream)
3.加密:密钥流与明文进行异或运算得到密文
4.解密:秘文与密钥流进行异或运算得到明文
java的实现Rc4的代码:
public class Rc4Util {
private static final int SBOX_LENGTH = 256;
private static final int KEY_MIN_LENGTH = 6;
/**
* 加密
*
* @param message
* @param key
* @return
*/
public static byte[] encryptMessage(String message, String key) {
byte[] crypt = crypt(message.getBytes(StandardCharsets.UTF_8), key);
return crypt;
}
/**
* 解密
*
* @param message
* @param key
* @return
*/
public static String decryptMessage(byte[] message, String key) {
byte[] msg = crypt(message, key);
return new String(msg, StandardCharsets.UTF_8);
}
public static byte[] crypt(final byte[] msg, String key) {
byte[] keyBytes = getKey("123456");
if (keyBytes == null) {
return null;
}
//SBox
int[] sbox = initSBox(keyBytes);
byte[] code = new byte[msg.length];
int i = 0;
int j = 0;
for (int n = 0; n < msg.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + sbox[i]) % SBOX_LENGTH;
swap(i, j, sbox);
int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
code[n] = (byte) (rand ^ msg[n]);
}
return code;
}
private static int[] initSBox(byte[] key) {
int[] sbox = new int[SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
sbox[i] = i;
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + sbox[i] + (key[i % key.length]) & 0xFF) % SBOX_LENGTH;
swap(i, j, sbox);
}
return sbox;
}
private static void swap(int i, int j, int[] sbox) {
int temp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = temp;
}
public static byte[] getKey(String key) {
if (key.length() <KEY_MIN_LENGTH || key.length() > SBOX_LENGTH) {
System.out.println("Key length has to be between "
+ KEY_MIN_LENGTH + ", " + (SBOX_LENGTH - 1));
return null;
}
return key.getBytes();
}
public static void main(String[] args) {
byte[] en = Rc4Util.encryptMessage("Rc4加密", "123456");
String base = Base64.getEncoder().encodeToString(en);
System.out.println(base);
String d = Rc4Util.decryptMessage(Base64.getDecoder().decode(base), "123456");
System.out.println(d);
}
}