我正在尝试用Java中的RC4
编写加密和解密输入文本的代码。有谁知道如何解决它?
我的代码:
import java.util.Arrays;
public class RC4 {
private static final int SBOX_LEN = 256;
private static final int MIN_KEY_LEN = 5;
private byte[] key = new byte[SBOX_LEN - 1];
private int[] sbox = new int[SBOX_LEN];
public RC4() {
initialize();
}
public RC4(String key) {
this();
setKey(key);
}
public static void main(String[] args) {
RC4 rc4 = new RC4();
byte[] cipherText = rc4.encryptMessage(args[0], args[1]);
System.out.println(Arrays.toString(cipherText));
String plainText = rc4.decryptMessage(cipherText, args[1]);
System.out.println(plainText);
}
private void initialize() {
Arrays.fill(key, (byte) 0);
Arrays.fill(sbox, 0);
}
public byte[] encryptMessage(String message, String key) {
initialize();
setKey(key);
byte[] crypt = crypt(message.getBytes());
initialize();
return crypt;
}
public String decryptMessage(byte[] message, String key) {
initialize();
setKey(key);
byte[] msg = crypt(message);
initialize();
return new String(msg);
}
public byte[] crypt(final byte[] msg) {
sbox = initializeSBox(key);
byte[] code = new byte[msg.length];
int i = 0;
int j = 0;
for (int n = 0; n < msg.length; n++) {
i = (i + 1) % SBOX_LEN;
j = (j + sbox[i]) % SBOX_LEN;
swap(i, j, sbox);
int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LEN];
code[n] = (byte) (rand ^ msg[n]);
}
return code;
}
private int[] initializeSBox(byte[] key) {
int[] sbox = new int[SBOX_LEN];
int j = 0;
for (int i = 0; i < SBOX_LEN; i++) {
sbox[i] = i;
}
for (int i = 0; i < SBOX_LEN; i++) {
j = ((j + sbox[i] + (key[i % key.length])) & 0xFF) % SBOX_LEN;
swap(i, j, sbox);
}
return sbox;
}
private void swap(int i, int j, int[] sbox) {
int temp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = temp;
}
public void setKey(String key) {
if (!((key.length() >= MIN_KEY_LEN) && (key.length() < SBOX_LEN))) {
throw new RuntimeException(String.format("Key length must be between %d and %d", MIN_KEY_LEN, SBOX_LEN - 1));
}
this.key = key.getBytes();
}
}
答案 0 :(得分:1)
RC4是一个坏算法,如果要高度保护数据,建议不要再使用它。
如果仍然需要有效的实现,则无需在代码中重新创建算法。 Java API javax.crypto可以为您完成此任务。只需生成一个密钥,然后将init方法设置为加密/解密模式即可。
static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
byte[] testDataBytes = "testString".getBytes();
KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
SecretKey key = rc4KeyGenerator.generateKey();
// Create Cipher instance and initialize it to encrytion mode
Cipher cipher = Cipher.getInstance("RC4"); // Transformation of the algorithm
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherBytes = cipher.doFinal(testDataBytes);
// Reinitialize the Cipher to decryption mode
cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
byte[] testDataBytesDecrypted = cipher.doFinal(cipherBytes);
System.out.println("Decrypted Data : "+new String(testDataBytesDecrypted));
return new String(testDataBytesDecrypted);
}
如果您需要将加密的数据作为url的一部分发送,请使用Base64Encoding然后发送。
例如
static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
byte[] plainBytes = "testString".getBytes();
KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
SecretKey key = rc4KeyGenerator.generateKey();
// Create Cipher instance and initialize it to encrytion mode
Cipher cipher = Cipher.getInstance("RC4"); // Transformation of the algorithm
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherBytes = cipher.doFinal(plainBytes);
String encoded = encodeBase64(cipherBytes);
String decoded = decodeBase64(encoded);
// Reinitialize the Cipher to decryption mode
cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
byte[] plainBytesDecrypted = cipher.doFinal(Hex.decode(decoded));
System.out.println("Decrypted Data : "+new String(plainBytesDecrypted));
return new String(plainBytesDecrypted);
}
static String decodeBase64(String encodedData){
byte[] b = Base64.getDecoder().decode(encodedData);
String decodedData = DatatypeConverter.printHexBinary(b);
return decodedData;
}
static String encodeBase64(byte[] data){
byte[] b = Base64.getEncoder().encode(data);
String encodedData = new String(b);
/*String encodedData = DatatypeConverter.printHexBinary(b);*/
return encodedData;
}
**提示:**如上所示,使用Hex.decode从base64解码的字符串中获取字节,否则会出现编码问题。尽可能使用十六进制进行转换,并使用Bouncycastle方法转换为字节数组。
需要进口:
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;
此外,如果您是根据自己的字符串生成密钥的,则可以使用MD5Hashing进行加密。