java中的rc4加密和解密

时间:2013-11-27 06:23:18

标签: java encryption rc4-cipher

我尝试过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;

     }
}

2 个答案:

答案 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();
    }

    }

提示:使用十六进制进行二进制转换,反之亦然,以摆脱编码问题。

输出:

enter image description here

希望这会有所帮助!

答案 1 :(得分:0)

RC4是一种面向字节的算法。 Java字符不是字节。但您可以根据需要将字符串转换为字节数组。欢迎查看我的实施here

转换为使用UTF-8编码的字符串:

new String(bytes, "UTF-8");

和一个字节数组:

str.getBytes("UTF-8");

如果您没有使用像UTF-8这样的简单编码,请使用CharsetEncoder