RC4, C++, and Python implementation

Recent work log module, there is a demand is the need to write log encryption into the file, and then read the file and then decrypt it. So this encryption and decryption method chose RC4.

Baidu encyclopedia at RC4, described as follows:

RC4 encryption algorithm is the famous RSA three group of the number one person, Ronald Rivest designed in 1987 the key length variable stream encryption algorithm cluster. It is called a cluster because the length of the S-box in its kernel can be arbitrary, but it is usually 256 bytes. The speed of the algorithm can reach about 10 times that of DES encryption, and has high level of nonlinearity. RC4 was originally designed to protect trade secrets. But in September 1994, when its algorithm was published on the Internet, there was no longer any trade secrets. RC4 is also called ARC4 (Alleged RC4 - the so-called RC4) because RSA has never officially published this algorithm.

RC4 algorithm principle is divided into two steps: initialization algorithm (KSA) and pseudo slave code generation algorithm (PRGA) two major parts.

C++ implements as follows:

Rc4.h file

Class RC4 {public: RC4 (void); rc4_init (unsigned char *key unsigned, long Len); / / void do_crypt encryption / decryption (unsigned char *Data unsigned, long Len); private: int m_box[256]; / / replacement box in box int symmetric encryption S m_index_i; int m_index_j;};

Rc4.cpp file

RC4:: (RC4) {m_index_i = 0; m_index_j = 0;} / / void RC4:: rc4_init initialization algorithm (unsigned char *key unsigned, long Len) {if (key = = NULL || Len = = 0) {printf ("RC4 key or len is 0, return!"); return;} / / for cycle 0 to 255 non repeating elements into the S box of for (int i = 0; I 256; < i++) {m_box[i] = I;} / / for cycle according to the key upset S box int j = 0; unsigned char TMP; for (int i = 0; I 256; < i++) {J = (j + m_box[i] + key[i% Len%]) 256; TMP = m_box[i]; m_box[i] = m_box[j]; / / m_box[j] and m_box[j] exchange m_box[i] = TMP;}}: void RC4: do_crypt (unsigned char *Data unsigned, long Len) {/ / each received a word Section, while cycle. Through certain algorithms ((a), (b)), locate an element in the S box, and XOR it with the input byte to obtain K. The S box ((c)) is also changed in the loop. If the input is plaintext, the output is ciphertext; if the input is ciphertext, the output is plain text. Unsigned char TMP for (unsigned long; k = 0; K < Len; k++) {m_index_i = (m_index_i + 1)% 256; / / a = m_index_j (m_index_j + m_box[m_index_i])% 256 / / B; TMP = m_box[m_index_i]; m_box[m_index_i] = m_box[m_index_j]; / / m_box[x] exchange and m_box[y] m_box[m_index_j] = TMP; / / generation pseudo random number int = R (m_box[m_index_i] + m_box[m_index_j])% 256; Data[k] ^ m_box[r];}}

Python implementations are as follows:

Rc4.py file

# coding=utf-8 class RC4: def __init__ (self, public_key = None): if not public_key: public_key ='none_public_key'self.public_key = public_key self.index_i = 0; self.index_j = 0; self._init_box (DEF) _init_box (self): "the initial permutation box" self.Box = range (256) key_length = len (J = self.public_key) 0 for I in range (256): index = ord (self.public_key[(I% key_length)] (J) = j + self.Box[i] + index)% 256 self.Box[i], self.Box[j] = self.Box[j], self.Box[i] def do_crypt (self, string): "the encryption / decryption string: to encrypt / decrypt the string" O UT for s in string: self.index_i [] = = (self.index_i + 1)% 256 = self.index_j (self.index_j + self.Box[self.index_i])% 256 self.Box[self.index_i], self.Box[self.index_j] = self.Box[self.index_j], self.Box[self.index_i] = R (self.Box[self.index_i] + self.Box[self.index_j])% 256 R = self.Box[r] # generated pseudo-random number out.append (Chr (ord (s) ^ R)) return''.join (out)

Pit encountered

A lot of information online, many people are given the RC4 algorithm, because the client will always write data to a file, so the RC4 initialization, will repeatedly calls to the do_crypt method, the pit is first encountered: C++ encryption, decryption when using Python, often can only decrypt the beginning of a sentence, after is garbled. The solution is: the m_index_i and m_index_j as a member variable, so many times after the call, the symmetric encryption in the replacement box, S box data will continue rolling, decryption can be completed.