RC4 in 1987, like the DES algorithm, is a symmetric encryption algorithm, which means that the key used is a single key (or a private key). However, unlike DES, RC4 does not group the plaintext, but instead encrypts each byte of the plaintext in the same way, and decrypts every byte in the ciphertext in turn.
RC4 algorithm is characterized by simple algorithm, fast running speed, and the key length is variable, variable range of 1-256 bytes (8-2048 bits), under the premise of today's technology support, when the key length is 128 bit, the brute force method to search for the key is not feasible, So it is foreseeable that the key range of the RC4 can withstand brute force search key attacks for a considerable amount of time in the future. In fact, no effective attack method is found for the RC4 encryption algorithm with 128bit key length.
Before introducing the principles of the RC4 algorithm, take a look at some of the key variables in the algorithm:
1, Key stream: The key of the RC4 algorithm is to generate the corresponding key stream according to the plaintext and the key, the length of the key stream corresponds to the length of the plaintext, that is, the length of the plaintext is 500 bytes, then the key stream is 500 bytes. Of course, the cipher generated ciphertext is also 500 bytes, because ciphertext i byte = plaintext I byte ^ key stream byte I;
2, State vector S: Length of 256,s[0],s[1] ..... S[255]. Each cell is a byte, and at any time the algorithm runs, S includes a permutation of 0-255 of the 8-bit number, but the position of the value changes;
3, Temporary vector t: The length is also 256, each unit is also a byte. If the length of the key is 256 bytes, the value of the key is assigned directly to T, otherwise, each byte of the key is assigned to T;
4, Key k: Length of 1-256 bytes, note that the length of the key keylen and the length of the plaintext, the length of the key stream is not necessarily related to the length of the key is usually fun 16 bytes (128 bits).
The principle of RC4 is divided into three steps:
1. Initialize S and t
For i=0 to 255 do
S[i] =i;
t[i]=k[Imodkeylen];
2. Initial arrangement S
For i=0 to 255 do
J= (J+s[i]+t[i]) mod256;
Swap (s[i],s[j]);
3. Generate a key stream
For r=0 to Len does//r for clear text length, R bytes
i= (i+1) mod 256;
J= (J+s[i]) mod 256;
Swap (s[i],s[j]);
T= (S[i]+s[j]) mod 256;
K[R]=S[T];
The following gives the C + + implementation of RC4 encryption decryption:
Encryption class:
/*Encryption Class*/classRC4 { Public: /*constructor, parameter is key length*/RC4 (intKL): Keylen (KL) {Srand ((unsigned) time (NULL)); for(intI=0; i<kl;++i) {//random production of a keylen-byte-length key intTmp=rand ()% the; K.push_back (Char(TMP)); } } /*Yuming Produce ciphertext*/ voidEncryption (Const string&,Const string&,Const string&);Private: UnsignedChars[ the];//state vector, total 256 bytesUnsignedChart[ the];//temporary vector, total 256 bytes intKeylen;//Key length, Keylen bytes, with a value range of 1-256vector<Char> K;//variable length keyvector<Char> k;//Key Stream /*initializes the state vector s and temporary vector T for Keystream method invocation*/ voidInitial () { for(intI=0;i< the;++i) {S[i]=i; T[i]=k[i%Keylen]; } } /*initial permutation state vector s, for Keystream method invocation*/ voidRangeS () {intj=0; for(intI=0;i< the;++i) {J= (J+s[i]+t[i])% the; //cout<< "j=" <<j<<endl;s[i]=s[i]+R[j]; S[J]=s[i]-S[j]; S[i]=s[i]-S[j]; } } /*generate key Stream len: Clear text is len bytes*/ voidKeystream (intlen);};voidRc4::keystream (intLen) {initial (); RangeS (); intI=0, j=0, T; while(len--) {i= (i+1)% the; J= (J+s[i])% the; S[i]=s[i]+S[j]; S[J]=s[i]-R[j]; S[i]=s[i]-S[j]; T= (S[i]+s[j])% the; K.push_back (S[t]); }}voidRc4::encryption (Const string&plaintext,Const string&ks,Const string&ciphertext) {Ifstreaminch; Ofstream out, Outks; inch. open (plaintext); //gets the length of the input stream inch. SEEKG (0, Ios::end); intlenfile=inch. TELLG (); inch. SEEKG (0, Ios::beg); //Production Key Streamkeystream (Lenfile); Outks.open (KS); for(intI=0; i<lenfile;++i) {Outks<<(K[i]); } outks.close (); //plaintext content read into bitsUnsignedChar*bits=NewUnsignedChar[Lenfile]; inch. Read (Char*) bits,lenfile); inch. Close (); out. open (ciphertext); //output plaintext to a ciphertext file by byte-to-stream or post -key for(intI=0; i<lenfile;++i) { out<< (unsignedChar) (bits[i]^K[i]); }<span style="White-space:pre"> </span> out. Close (); Delete[]bits;}
Decryption class:
/*Decryption Class*/classrc4_decryption{ Public: /*constructors, parameters are key stream files and ciphertext files*/Rc4_decryption (Const stringKsConst stringCT): keystream (KS), ciphertext (CT) {}/*decryption method, parameter is decrypt file name*/ voidDecryption (Const string&);Private: stringCiphertext,keystream;};voidRc4_decryption::d ecryption (Const string&Res) {Ifstream INKS,INCP; Ofstream out; Inks.open (keystream); Incp.open (ciphertext); //calculating the length of the cipher textINKS.SEEKG (0, Ios::end); Const intlenfile=Inks.tellg (); INKS.SEEKG (0, Ios::beg); //read-in key streamUnsignedChar*bitkey=NewUnsignedChar[Lenfile]; Inks.read ((Char*) bitkey,lenfile); Inks.close (); //read in ciphertextUnsignedChar*bitcip=NewUnsignedChar[Lenfile]; Incp.read ((Char*) bitcip,lenfile); Incp.close (); //decryption results output to decrypted file out. Open (res); for(intI=0; i<lenfile;++i) out<< (unsignedChar) (bitkey[i]^Bitcip[i]); out. Close ();}
When implementing the program, it is important to note that the type of the state vector array s and the temporary vector array T should be set to unsigned char instead of char. Because in some machines, the char default as signed char, in the algorithm when the subscript i,j, will involve a char to int, if it is signed char, then the 8 bits of char is copied to the lower 8 bits of int, also according to the symbol of char, Fill 0 or 1 in the high position of Int. Since the key is randomly generated, if a byte of a key is encountered with a high point of 1, then the computed array subscript is negative, it will be out of bounds.
Program Run Example
Main function:
intMain () {RC4 RC4 ( -);//key length 16 bytesRc4.encryption ("plaintext. txt","Key stream. txt","cipher. txt"); Rc4_decryption Decrypt ("Key stream. txt","cipher. txt"); Decrypt.decryption ("decrypting a file. txt");}
Clear text: I love bunnies!
Ciphertext: ' 柀 l&t 餥 6 Chau
Key stream: Bo fake pinacol 3 toric u
Decrypt file: I love bunny!
Because the RC4 algorithm encryption is the XOR, so, once the sub-key sequence has been duplicated, ciphertext can be cracked. For more information on how to hack XOR encryption, please see the 1.4 Simple XOR in Applied cryptography of Bruce Schneier, which I will not dwell on. So, does the RC4 algorithm generate a sub-key sequence that repeats itself? After my testing, there is a partial weak key, so that the sub-key sequence in less than 1 million bytes of the complete repetition, if it is partially repeated, it may be in less than 100,000 bytes can be duplicated, so it is recommended to use the RC4 algorithm, the encryption key must be tested to determine whether it is a weak key.
RC4 online encryption and decryption URL: http://encode.chahuo.com
RC4 Encryption algorithm