【问题标题】:rc4 encryption and decryption in javajava中的rc4加解密
【发布时间】:2013-11-27 06:23:18
【问题描述】:

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

     }
}

【问题讨论】:

    标签: java encryption rc4-cipher


    【解决方案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();
        }
    
        }
    

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

    输出:

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

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

      转成UTF-8编码的字符串:

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

      到一个字节数组:

      str.getBytes("UTF-8");
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-09
        • 1970-01-01
        相关资源
        最近更新 更多