我尝试过RC4加密和解密程序。我一直在使用代码行s2=key.charAt(j++)
收到错误
调试器告诉我它无法从 char 解析为 int 。
输出运行直到进入密钥流。 XOR操作无效
任何人都可以指出一个可能的解决方案吗?
import java.util.Scanner;
public class Rc4
{
//global
public static int SIZE=256;
public static int[] s1 = new int[SIZE+1]; //filled with random numbers
public static int[] s2 = new int[SIZE+1]; //filled with keytext
public static int i,j;
public static String key, input;
public static void main(String[] args)
{
Scanner keyboard= new Scanner(System.in);
System.out.print("En/Decrypt:");
input = keyboard.nextLine();
System.out.print("Enter key :");
key = keyboard.nextLine();
INIT();
KSA();
}
static void INIT()
{
j=0;
for(i=0; i<SIZE; i++)
{
if(j==key.length())
j=0;
s2= key.charAt(j++);
}
}
static void KSA()
{
for( i=0; i<SIZE; i++)
s1[i]=i;
j=0;
for(int i=0; i<SIZE; i++)
{
j = (j + s1[i] + s2[i]) % SIZE;
swap(i, j);
}
}
static void PRGA()
{
int Rand=0;
//print();
j=i=0;
for(int x = 0; x< input.length(); x++)
{
i = (i + 1) % SIZE;
j = (j + s1[i]) % SIZE;
swap(i, j);
Rand = (char)s1[ ((s1[i] + s1[j]) % SIZE)];
System.out.print((char)(input.charAt(x) ^ Rand) );
}
}
static void print()
{
System.out.print("\n");
for(int y=0; y<input.length(); y++)
{
System.out.print(input.charAt(y));
}
System.out.print("\n");
}
static void swap(int i, int j)
{
int temp = s1[i];
s1[i]= s1[j];
s1[j] = temp;
}
}
答案 0 :(得分:1)
您可以使用org.bouncycastle api的十六进制和二进制转换来实现转换而不会出现编码问题。内置的crypto API可以为您进行加密/解密。
类似这样的东西:
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
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.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;
public class RC4Algo {
public static void main(String args[])throws IOException, NoSuchAlgorithmException, DecoderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
{
decryptRC4();
}
static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException{
byte[] plainBytes = "testString".getBytes();
String hashedKey = hashedData("thisismysecretkey");
//Generate a new key using KeyGenerator
/*KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
SecretKey key = rc4KeyGenerator.generateKey();*/
Key key = new SecretKeySpec(Hex.decode(hashedKey), "RC4"); //String to key conversion using Hex.decode to convert to byte []
// 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;
}
static String hashedData(String key) throws NoSuchAlgorithmException{
String password = key;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
提示:使用十六进制进行二进制转换,反之亦然,以摆脱编码问题。
输出:
希望这会有所帮助!
答案 1 :(得分:0)
RC4是一种面向字节的算法。 Java字符不是字节。但您可以根据需要将字符串转换为字节数组。欢迎查看我的实施here。
转换为使用UTF-8编码的字符串:
new String(bytes, "UTF-8");
和一个字节数组:
str.getBytes("UTF-8");
如果您没有使用像UTF-8这样的简单编码,请使用CharsetEncoder
。