$$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Self-defined math definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Math symbol commands \newcommand{\intd}{\,{\rm d}} % Symbol 'd' used in integration, such as 'dx' \newcommand{\diff}{{\rm d}} % Symbol 'd' used in differentiation ... $$

对称加密-流加密-RC4

  RC4 加密算法是由 Ron Rivest 在上世纪90年代左右提出的一种对称加密算法。其最大的特点是运行速度快。RC4 加解密的基本原理如下图.

  RC4 设计是面向字节操作的,可变密钥长度的加密算法。该算法设计的基础是随机置换。其中,RC4 算法的核心在于密钥流( keystream )的生成。密钥流生成的过程涉及到两个基本算法:密钥调度算法(KSA)和伪随机数生成算法(PRGA)。

  KSA 算法的核心是利用密钥 K 来生成 S 表。开始时,S 中的元素被按照升序初始化,即 S[0] = 0, S[1] = 1, S[2] = 2, ..., S[255] = 255。之后新建一个初始化向量 T,倘若密钥长度大于 255,则将密钥 K 赋值给 T,否则,将密钥 K 的值依次赋值给 T 中的元素并反复赋值,直到填满为止。

//=========== initialize S_Box ==============
    for(int i = 0; i < 256; i++){
        S_box[i] = i;
        Temp[i]  = Key[i % key_length];
    }
    
//========== permutation S_Box ==============
    int j = 0;//初始化j
    for(int i = 0; i < 256; i++){
        j = (j + S_box[i] + Temp[i]) % 256;//计算新的j值
        swap(S_box[i], S_box[j]);//交换S[i]和S[j]
    }

   在完成 KSA 算法之后,就需要进入随机数生成算法(PRGA),从 S 表当中读取字节单元,输出密钥流序列.

int i = 0,j = 0;
while(true)
{
    i = (i + 1) % 256;
    j = (j + S_box[i]) % 256;
    swap(S_box[i], S_box[j]);
    t = (S_box[i] + S_box[j]) % 256;
    //输出一字节的密钥流序列k
    k = S_box[t];
}

   实现算法。

#include<iostream>
#include<array>
#include<string>
using namespace std;

//===========Swap the values=============
void Swap(int &S_box1, int &S_box2){
    S_box1 ^= S_box2;
    S_box2 ^= S_box1;
    S_box1 ^= S_box2;
}

//=========initialize S Box================
void init_Sbox(array<int, 256> &S_box, array<int, 256> &Temp, string Key){
//初始化S盒
    for(int i = 0; i < 256; i++){
        S_box[i] = i;
        Temp[i]  = Key[i % Key.length()];
    }
    
//对S盒中的元素置换
    int j = 0;
    for(int i = 0; i < 256; i++){
        j = (j + S_box[i] + Temp[i]) % 256;
        Swap(S_box[i], S_box[j]);
    }
}

//==========generate keystream===============
void GengrateKeystream(array<int, 256> &S_box, int plain_length, array<int, 512> &Keystream){
    int i = 0, j = 0;
    for(int k = 0; k < plain_length; k++){
        i = (i + 1) % 256;
        j = (j + S_box[i]) % 256;
        Swap(S_box[i], S_box[j]);
        int t = (S_box[i] + S_box[j]) % 256;
        //输出一字节的密钥流序列k
        Keystream[k] = S_box[t];
    }
}

int main(void){
    array<int, 256> S_box;
    array<int, 256> Temp;
    array<int, 512> Keystream;
    string Plaintext = "hello world! This is a test.";
    string Key = "absbjkabjabjka@bhdbh&V%VGHJ%$VHJ&cbb.//j";
    string Ciphertext;
    
    cout << "Plaintext is: " << Plaintext << endl;
    cout << "Key is: " << Key << endl;
    
    init_Sbox(S_box, Temp, Key);
    cout << "S Box is: " << endl;
    for(int i = 0; i<256; i++){
        cout <<"\t" << S_box[i];
        if(i % 10 == 0)
            cout << endl;
    }
    
    GengrateKeystream(S_box, Plaintext.length(), Keystream);
    cout << endl << "Keystream is: " << endl;
    for(int i = 0; i<Plaintext.length(); i++)
        cout <<"\t" << Keystream[i];
    
//==============Encryption===========================
    for(int i = 0; i<Plaintext.length(); i++)
        Ciphertext += char(Keystream[i] ^ (int)Plaintext[i]);
    Ciphertext[Plaintext.length()] =  '\0';
    cout << endl << "Ciphertext is: "  ;

//==============Decryption============================
    cout << endl << "Plaintext is: " ;
    for(int i = 0; i<Plaintext.length(); i++){
        cout << char(Keystream[i] ^ (int)Ciphertext[i]);
    }
    
    return 0;
}

  运行结果。我们可以发现数据按照密钥流被加密了。 

   RC4的缺陷。由于RC4加密算法的简单性和快捷性,这种算法被用于诸多的协议当中。2013年,科学家利用这个RC4中的统计偏差设计了一次攻击实验:他们在2000小时内猜出一个基础身份认证cookie中包含的字符。后来技术改进后,研究人员只需约75小时猜解就能得到94%的准确率。随着计算机算力的不断发展,RC4也被研究人员认为是不再安全的加密算法,建议人们不要使用。

 

参考资料

[1] RC4加密算法,博客园,https://www.cnblogs.com/shelmean/p/14281332.html。

[2] RC4 已不再安全,破解效率极高,博客园,https://www.cnblogs.com/likefrank/p/rc4-is-not-safe.html。

posted @ 2023-04-04 11:33  素衣叹风尘  阅读(236)  评论(0)    收藏  举报