java - java中的rc4加密和解密

标签 java encryption rc4-cipher

我尝试过研究RC4加密和解密程序。我不断收到代码行 s2=key.charAt(j++) 的错误。
调试器告诉我无法将其从 char 解析为 int
输出一直运行直到输入 key 流。 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;

     }
}

最佳答案

您可以使用 org.bouncycaSTLe api 的十六进制和二进制转换来实现转换,而不会出现编码问题。内置加密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

希望这有帮助!

关于java - java中的rc4加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20235354/

相关文章:

c# - RC4 加密 KSA key 越界

java - 从java中的单个三元运算符返回多个值

java - 返回 jsoup 中 div 之间的文本

php - 通过公共(public)互联网安全发送数据的替代方法

Node.js:尝试解密加密的对称 key 时出现无效的 RSAES-OAEP 填充

c - 如何从解密和加密的数据中找到 RC4 key ?

java - 从 servlet 调用图像和链接

java - 修改和访问线程类之外的值

Python加密函数和全局变量

c++ - 编写使用 RC4 流密码的 C++ iostream。如何优化我的实现?