嗨,我正在努力用Java实现RC4算法。我发现这个代码是帮助我理解这个想法的一个例子:
public class RC4 {
private int[] S = new int[256];
private int[] T = new int[256];
private int keylen;
public RC4(byte[] key) throws Exception {
if (key.length < 1 || key.length > 256) {
throw new Exception("key must be between 1 and 256 bytes");
} else {
keylen = key.length;
for (int i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % keylen];
}
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
S[i] ^= S[j];
S[j] ^= S[i];
S[i] ^= S[j];
}
}
}
public int[] encrypt(int[] plaintext) {
int[] ciphertext = new int[plaintext.length];
int i = 0, j = 0, k, t;
for (int counter = 0; counter < plaintext.length; counter++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
S[i] ^= S[j];
S[j] ^= S[i];
S[i] ^= S[j];
t = (S[i] + S[j]) % 256;
k = S[t];
ciphertext[counter] = plaintext[counter] ^ k;
}
return ciphertext;
}
public int[] decrypt(int[] ciphertext) {
return encrypt(ciphertext);
}
}我没有什么问题:
int数组?结果是:(原文和回文本不一样)为什么?
original text: 12345
cipher: 1483188254174
back to text: 391501310217发布于 2012-09-05 22:53:48
有几件事需要注意:
S和T中创建了一个状态,那么当您使用相同的实例解密时,您应该注意到这些值发生了变化;byte[]之后,首先需要使用字符编码,例如使用String.getBytes(Charset charset)(http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes(java.nio.charset.Charset%29);为了让生活更简单,并在深夜进行一些有趣的黑客攻击,我改进了您的代码,并使用零d输出字节数组对rfc6229中的单个向量进行了测试。
更新:正如micahk在下面指出的那样,使用的邪恶的C XOR交换阻止了该代码加密Java中输入的最后字节。使用常规的旧掉期来修复它。
警告:下面的代码应该被视为编码练习。请使用经过良好审核的库来执行RC4 (或Ron的代码4、ARC4等),而不是下面的代码片段。在你的申请中。这意味着使用Cipher.getInstance("RC4");或ARC4类。
public class RC4 {
private final byte[] S = new byte[256];
private final byte[] T = new byte[256];
private final int keylen;
public RC4(final byte[] key) {
if (key.length < 1 || key.length > 256) {
throw new IllegalArgumentException(
"key must be between 1 and 256 bytes");
} else {
keylen = key.length;
for (int i = 0; i < 256; i++) {
S[i] = (byte) i;
T[i] = key[i % keylen];
}
int j = 0;
byte tmp;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) & 0xFF;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
}
}
}
public byte[] encrypt(final byte[] plaintext) {
final byte[] ciphertext = new byte[plaintext.length];
int i = 0, j = 0, k, t;
byte tmp;
for (int counter = 0; counter < plaintext.length; counter++) {
i = (i + 1) & 0xFF;
j = (j + S[i]) & 0xFF;
tmp = S[j];
S[j] = S[i];
S[i] = tmp;
t = (S[i] + S[j]) & 0xFF;
k = S[t];
ciphertext[counter] = (byte) (plaintext[counter] ^ k);
}
return ciphertext;
}
public byte[] decrypt(final byte[] ciphertext) {
return encrypt(ciphertext);
}
}编码愉快。
发布于 2013-11-27 02:29:44
由于使用xor-交换技术,Java代码有一个错误:
S[i] ^= S[j];
S[j] ^= S[i];
S[i] ^= S[j];而不是这样,您需要使用一个临时变量,如下所示。我还没有深入探究为什么xor交换的结果不像预期的那样,但是我有解密错误,这些错误都是通过简单的直接交换解决的。我怀疑这是为了执行xor操作而从字节到int的隐式转换的一个微妙的副作用。
public class RC4 {
private final byte[] S = new byte[256];
private final byte[] T = new byte[256];
private final int keylen;
public RC4(final byte[] key) {
if (key.length < 1 || key.length > 256) {
throw new IllegalArgumentException(
"key must be between 1 and 256 bytes");
} else {
keylen = key.length;
for (int i = 0; i < 256; i++) {
S[i] = (byte) i;
T[i] = key[i % keylen];
}
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) & 0xFF;
byte temp = S[i];
S[i] = S[j];
S[j] = temp;
}
}
}
public byte[] encrypt(final byte[] plaintext) {
final byte[] ciphertext = new byte[plaintext.length];
int i = 0, j = 0, k, t;
for (int counter = 0; counter < plaintext.length; counter++) {
i = (i + 1) & 0xFF;
j = (j + S[i]) & 0xFF;
byte temp = S[i];
S[i] = S[j];
S[j] = temp;
t = (S[i] + S[j]) & 0xFF;
k = S[t];
ciphertext[counter] = (byte) (plaintext[counter] ^ k);
}
return ciphertext;
}
public byte[] decrypt(final byte[] ciphertext) {
return encrypt(ciphertext);
}
}发布于 2012-09-05 21:14:12
您的整数数组S和T尚未构造。因此,一旦尝试使用NullPointerException,就会得到它们。
看看其余的代码,我猜它们应该是256项数组:
private int[] S = new int[256];
private int[] T = new int[256];https://stackoverflow.com/questions/12289717
复制相似问题