RC4加密原理步骤

RC4

对明文使用同一个**异或两次最后是得到原文的

明文,是指没有加密的文字(或者字符串),一般人都能看懂的意思。

密文,是指经过某个加密算法,把一个明文,变成另一些文字。从密文本身,一般不能看出明文本身的意思 。不然就失去加密的意义。要想得到明文,就能通过对应的解密算法,才能得到明文 ,从而知道本来的意思 。

1.简介

在密码学中,RC4(来自 Rivest Cipher 4 的缩写)是一种流加密算法,**长度可变。它加解密使用相同的**,因此也属于对称加密算法。RC4 是有线等效加密(WEP)中采用的加密算法,也曾经是 TLS 可采用的算法之一。

2.原理及步骤

(图片转载地址:https://www.cnblogs.com/block2016/p/5601925.html)
RC4加密原理步骤

1>先初始化状态向量S(256个字节,用来作为**流生成的种子1)

按照升序,给每个字节赋值0,1,2,3,4,5,6…,254,255

for (int i=0;i<256;i++){
    S[i] = i
}
2>初始**(由用户输入),长度任意

如果输入长度小于256个字节,则进行轮转,直到填满
例如输入**的是1,2,3,4,5 , 那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5…
由上述轮转过程得到256个字节的向量T(用来作为**流生成的种子2)

3>开始对状态向量S进行置换操作(用来打乱初始种子1)

按照下列规则进行

从第零个字节开始,执行256次,保证每个字节都得到处理

 j = 0;
  for (i = 0 ; i < 256 ; i++){
    j = (j + S[i] + T[i]) mod 256;
    swap(S[i] , S[j]);
  }

这样处理后的状态向量S几乎是带有一定的随机性了

4>最后是秘钥流的生成与加密,很多人在这里不是特别理解,别的博客也没有写的很简洁明了

假设我的明文字节数是datalength=1024个字节(当然可以是任意个字节)
i=0;
j=0;
while(datalength–){//相当于执行1024次,这样生成的秘钥流也是1024个字节

   i = (i + 1) mod 256;
   j = (j + S[i]) mod 256;
   swap(S[i] , S[j]);
   t = (S[i] + S[j]) mod 256;
   k = S[t];这里的K就是当前生成的一个秘钥流中的一位
   //可以直接在这里进行加密,当然也可以将**流保存在数组中
   //最后进行异或就ok
   data[]=data[]^k; //进行加密,"^"是异或运算符
}

解密按照前面写的,异或两次就是原文,所以只要把**流重新拿过来异或一次就能得到原文了

这样就完成了一次生成**流及加密的过程,这也是RC4的全部工作

解释过程参考https://www.cnblogs.com/gambler/p/9075415.html

3.Java实现

public class MyRC4 {
 
    public static void main(String[] args) {
        MyRC4 rc4 = new MyRC4();
 
        String plaintext = "helloworld";
        String key = "hasdg";
 
        String ciphertext = rc4.encrypt(plaintext, key);
        String decryptText = rc4.encrypt(ciphertext, key);
 
        System.out.print(
                "明文为:" + plaintext + "\n" + "**为:" + key + "\n\n" + "密文为:" + ciphertext + "\n" + "解密为:" + decryptText);
    }
 
    /**
     * 3.加解密过程是一样的
     * 加密:明文流字与**流字XOR得到密文流字
     * 解密:密文流字与**流字XOR得到明文流字
     * */
    public String encrypt(final String plainOrCipherText, final String key) {
        Integer[] S = new Integer[256]; // S盒
        Character[] keySchedul = new Character[plainOrCipherText.length()]; // 生成的**流
        StringBuffer ciphertext = new StringBuffer();
 
        ksa(S, key);
        rpga(S, keySchedul, plainOrCipherText.length());
 
        for (int i = 0; i < plainOrCipherText.length(); ++i) {
            ciphertext.append((char) (plainOrCipherText.charAt(i) ^ keySchedul[i]));
        }
        return ciphertext.toString();
    }
    /*1.初始化向量S*/
    public void ksa(Integer[] s, String key) {
        for (int i = 0; i < 256; ++i) {
            s[i] = i;
        }
        int j = 0;
        for (int i = 0; i < 256; ++i) {
            j = (j + s[i] + key.charAt(i % key.length())) % 256;
            swap(s, i, j);
        }
    }
    /*2.伪随机生成算法*/
    public void rpga(Integer[] s, Character[] keySchedul, int plaintextLength) {
        int i = 0, j = 0;
        for (int k = 0; k < plaintextLength; ++k) {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            swap(s, i, j);
            keySchedul[k] = (char) (s[(s[i] + s[j]) % 256]).intValue();
        }
    }
    /*置换*/
    public void swap(Integer[] s, int i, int j) {
        Integer mTemp = s[i];
        s[i] = s[j];
        s[j] = mTemp;
    }
}

4.RC4的优点和缺陷

由于RC4算法加密是采用的xor,所以,一旦子**序列出现了重复,密文就有可能被**。RC4算法生成的子**序列是否会出现重复呢?由于存在部分弱**,使得子**序列在不到100万字节内就发生了完全的重复,如果是部分重复,则可能在不到10万字节内就能发生重复,因此,推荐在使用RC4算法时,必须对加***进行测试,判断其是否为弱**。其不足主要体现于,在无线网络中IV(初始化向量)不变性漏洞。

RC4已经成为一些常用的协议和标准的一部分,如1997年的WEP和2003/2004年无线卡的WPA; 和1995年的SSL,以及后来1999年的TLS。让它如此广泛分布和使用的主要因素是它不可思议的简单和速度,不管是软件还是硬件,实现起来都十分容易。