java - RC4加密java

标签 java encryption rc4-cipher

您好,我正在尝试用 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 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);
  }
}

我有几个问题:

  1. 为什么上面代码中明文是int数组?

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

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

这是结果:(原始和回文不一样)为什么???

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

最佳答案

有几点需要注意:

  • 当您需要无符号字节(例如用于索引)时,Java 不是很容易使用;
  • 如果您在 ST 中创建一个状态,当您使用相同的实例解密时,您应该真正注意到这些值发生了变化您采用用于加密的状态;
  • 上面的代码在内存方面不是很有效,你可以很容易地重写它以获取字节数组;
  • 要使用字符串,将参数重构为 byte[] 后,首先需要使用 首先,例如使用 String.getBytes(Charset charset) ;

为了让生活更轻松,并享受一些有趣的深夜黑客攻击,我改​​进了您的代码并针对 rfc6229 中的单个 vector 对其进行了测试使用归零字节数组。

更新:正如 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(
                    "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);
    }
}

快乐编码。

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

相关文章:

ssl - 我如何通过关闭SHA256,SHA384,SHA,MD5,AES 128/128恢复RDP连接到Windows Server 2012 R2(驻留在AWS上)?

java - Java中的并发读/写文件

java - String.h 中是否有返回子字符串的内置函数?

java - JAVA忽略越界异常的简单方法

encryption - clojure 有 AES 库吗?

windows - linux下如何处理CP-1252编码的密码?

java - 是否有 CheckStyle 规则强制 if else 关键字在 if/else 阶梯中位于同一行?

php - android 中的 Base64 和 mcrypt_encrypt

encryption - openssl 命令行来加密 RC4,不是预期的结果,不明白

base64 - 2 台不同机器上 CFML 中 toBase64() 的不同输出