RC4加密java [英] RC4 encryption java

查看:192
本文介绍了RC4加密java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Java中实现RC4算法。我发现这个 code 作为一个例子,帮助我理解这个想法:

  public class RC4 {
private int [] S = new int [256];
private int [] T = new int [256];
private int keylen;

public RC4(byte [] key)throws异常{
if(key.length< 1 || key.length> 256){
throw new Exception(密钥必须在1到256字节之间);
} else {
keylen = key.length; (int i = 0; i <256; i ++){
S [i] = i;
T [i] = key [i%keylen];
}
int j = 0; (int i = 0; i< 256; i ++){
j =(j + S [i] + T [i])%256;
S [i] ^ = S [j];
S [j] ^ = S [i];
S [i] ^ = S [j];
}
}
}

public int [] encrypt(int [] plaintext){
int [] ciphertext = new int [plaintext.length ]。
int i = 0,j = 0,k,t; (int counter = 0; counter< plaintext.length; counter ++){
i =(i + 1)%256;
j =(j + S [i])%256;
S [i] ^ = S [j];
S [j] ^ = S [i];
S [i] ^ = S [j];
t =(S [i] + S [j])%256;
k = S [t];
ciphertext [counter] = plaintext [counter] ^ k;
}
返回密文;
}

public int [] decrypt(int [] ciphertext){
return encrypt(ciphertext);
}
}

我有几个问题:


  1. 为什么上述代码中的纯文本是 int 数组?


  2. 当我测试这个代码时,我得到了奇怪的结果,有人可以向我解释吗?这里我的代码测试:

      public class RC4_Main {

    public static void main(String args [ ])throws Exception {
    String keyword =hello;
    byte [] keytest = keyword.getBytes(); //将关键字转换为字节

    int [] text = {1,2,3,4,5}; // text as 12345

    RC4 rc4 = new RC4(keytest);

    System.out.print(\\\
    original text:); (int i = 0; i< text.length; i ++){
    System.out.print(text [i]);

    }

    int [] cipher = rc4.encrypt(text); // encryption
    System.out.print(\\\
    cipher:); (int i = 0; i< cipher.length; i ++){
    System.out.print(cipher [i]);

    }

    int [] backtext = rc4.decrypt(cipher); // decrypt
    System.out.print(\\\
    back to text:); (int i = 0; i< backtext.length; i ++){
    System.out.print(backtext [i]);

    }
    System.out.println();
    }
    }


这是结果:(原始和回到文本不是SAME)为什么???

 原文:12345 
密码:1483188254174
返回文本:391501310217


解决方案

有一些事情需要注意:




  • 当您需要无符号字节(例如索引)时,Java不是很容易使用;

  • 如果您在 S T 中创建状态,您应该真的注意到这些值改变,当你使用相同的实例解密 时,你采用加密的状态;

  • 上面的代码不是非常有效的内存明智,您可以轻松地重写它来采取字节数组;

  • 使用一个String,在将参数重构为 byte [] 之后首先需要使用字符编码,首先,例如使用 String.getBytes(Charset charset) ;



更容易,并且有一些有趣的深夜黑客攻击,我改​​进了您的代码,并针对 rfc6229 使用零字节数组。



更新:由于micahk指出以下,使用的恶性C XOR交换阻止了此代码加密最终Java中的输入字节。使用常规的旧交换修复它。



警告:以下代码应被视为编码练习。请使用一个经过验证的库,而不是下面的代码片段在您的应用程序中执行RC4(或Ron的代码4,ARC4等)。这意味着使用 Cipher.getInstance(RC4); 或Bouncy Castle的ARC4类。

  public class RC4 {
private final byte [] S = new byte [256];
private final byte [] T = new byte [256];
private final int keylen;

public RC4(final byte [] key){
if(key.length< 1 || key.length> 256){
throw new IllegalArgumentException(
键必须在1到256字节之间);
} else {
keylen = key.length; (int i = 0; i <256; i ++){
S [i] =(byte)i;

T [i] = key [i%keylen];
}
int j = 0;
byte tmp; (int i = 0; i <256; i ++){
j =(j + S [i] + T [i])& 0xFF的;
tmp = S [j];
S [j] = S [i];
S [i] = tmp;
}
}
}

public byte [] encrypt(final byte [] plaintext){
final byte [] ciphertext = new byte [plaintext 。长度];
int i = 0,j = 0,k,t;
byte tmp; (int counter = 0; counter< plaintext.length; counter ++){
i =(i + 1)& 0xFF的;
j =(j + S [i])& 0xFF的;
tmp = S [j];
S [j] = S [i];
S [i] = tmp;
t =(S [i] + S [j])& 0xFF的;
k = S [t];
ciphertext [counter] =(byte)(plaintext [counter] ^ k);
}
返回密文;
}

public byte [] decrypt(final byte [] ciphertext){
return encrypt(ciphertext);
}
}

快乐编码


Hi there I am trying to implement the RC4 algorithm in Java. I found this code as an example that help me to understand the idea:

public class RC4 {
  private int[] S = new int[256];
  private int[] T = new int[256];
  private int keylen;

  public RC4(byte[] key) throws Exception {
    if (key.length < 1 || key.length > 256) {
      throw new Exception("key must be between 1 and 256 bytes");
    } else {
      keylen = key.length;
      for (int i = 0; i < 256; i++) {
        S[i] = i;
        T[i] = key[i % keylen];
      }
      int j = 0;
      for (int i = 0; i < 256; i++) {
        j = (j + S[i] + T[i]) % 256;
        S[i] ^= S[j];
        S[j] ^= S[i];
        S[i] ^= S[j];
      }
    }
  }

  public int[] encrypt(int[] plaintext) {
    int[] ciphertext = new int[plaintext.length];
    int i = 0, j = 0, k, t;
    for (int counter = 0; counter < plaintext.length; counter++) {
      i = (i + 1) % 256;
      j = (j + S[i]) % 256;
      S[i] ^= S[j];
      S[j] ^= S[i];
      S[i] ^= S[j];
      t = (S[i] + S[j]) % 256;
      k = S[t];
      ciphertext[counter] = plaintext[counter] ^ k;
    }
    return ciphertext;
  }

  public int[] decrypt(int[] ciphertext) {
    return encrypt(ciphertext);
  }
}

I have few question:

  1. Why is the plain-text an int array in the above code?

  2. When I test this code I get strange result, can somebody explain to me? Here my code to test:

    public class RC4_Main {
    
        public static void main(String args[]) throws Exception {
            String keyword = "hello";
            byte[] keytest = keyword.getBytes(); //convert keyword to byte
    
            int[] text = {1, 2, 3, 4, 5}; // text as 12345
    
            RC4 rc4 = new RC4(keytest);
    
            System.out.print("\noriginal text: ");
            for (int i = 0; i < text.length; i++) {          
                System.out.print(text[i]);          
            }    
    
            int[] cipher = rc4.encrypt(text); //encryption      
            System.out.print("\ncipher: ");
            for (int i = 0; i < cipher.length; i++) {          
                System.out.print(cipher[i]);          
            }    
    
            int[] backtext = rc4.decrypt(cipher); //decryption
            System.out.print("\nback to text: ");
            for (int i = 0; i < backtext.length; i++) {          
                System.out.print(backtext[i]);            
            } 
            System.out.println();
        }
    }
    

Here is the result: (original and back to text are not SAME) why???

original text: 12345
cipher: 1483188254174
back to text: 391501310217

解决方案

There are a few things to notice:

  • Java is not very easy to use when you require unsigned bytes (e.g. for indexing);
  • if you create a state in S and T, you should really notice that these values change, when you decrypt with the same instance you take the state used for encryption;
  • the above code is not very efficient memory wise, and you can easily rewrite it to take byte arrays;
  • to use a String, after refactoring the arguments to byte[], you first need to use first, e.g. using String.getBytes(Charset charset);

To make life easier, and to have some fun late night hacking, I improved your code and tested it against a single vector in rfc6229 using a zero'd out byte array.

UPDATE: As micahk points out below, the evil C XOR swap that was used prevented this code from encrypting the final byte of input in Java. Using regular old swaps fixes it.

Warning: the code below should be considered a coding exercise. Please use a well vetted library instead of the code snippet below to perform RC4 (or Ron's Code 4, ARC4 etc.) in your application. That means using Cipher.getInstance("RC4"); or the ARC4 classes in Bouncy Castle.

public class RC4 {
    private final byte[] S = new byte[256];
    private final byte[] T = new byte[256];
    private final int keylen;

    public RC4(final byte[] key) {
        if (key.length < 1 || key.length > 256) {
            throw new IllegalArgumentException(
                    "key must be between 1 and 256 bytes");
        } else {
            keylen = key.length;
            for (int i = 0; i < 256; i++) {
                S[i] = (byte) i;
                T[i] = key[i % keylen];
            }
            int j = 0;
            byte tmp;
            for (int i = 0; i < 256; i++) {
                j = (j + S[i] + T[i]) & 0xFF;
                tmp = S[j];
                S[j] = S[i];
                S[i] = tmp;
            }
        }
    }

    public byte[] encrypt(final byte[] plaintext) {
        final byte[] ciphertext = new byte[plaintext.length];
        int i = 0, j = 0, k, t;
        byte tmp;
        for (int counter = 0; counter < plaintext.length; counter++) {
            i = (i + 1) & 0xFF;
            j = (j + S[i]) & 0xFF;
            tmp = S[j];
            S[j] = S[i];
            S[i] = tmp;
            t = (S[i] + S[j]) & 0xFF;
            k = S[t];
            ciphertext[counter] = (byte) (plaintext[counter] ^ k);
        }
        return ciphertext;
    }

    public byte[] decrypt(final byte[] ciphertext) {
        return encrypt(ciphertext);
    }
}

Happy coding.

这篇关于RC4加密java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆