对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例
RC4是一種對稱密碼算法,它屬于對稱密碼算法中的序列密碼(streamcipher,也稱為流密碼),它是可變密鑰長度,面向字節操作的流密碼。
RC4是流密碼streamcipher中的一種,為序列密碼。RC4加密算法是Ron Rivest在1987年設計出的密鑰長度可變的加密算法簇。起初該算法是商業機密,直到1994年,它才公諸于眾。由于RC4具有算法簡單,運算速度快,軟硬件實現都十分容易等優點,使其在一些協議和標準里得到了廣泛應用。
流密碼也屬于對稱密碼,但與分組加密算法不同的是,流密碼不對明文數據進行分組,而是用密鑰生成與明文一樣長短的密碼流對明文進行加密,加解密使用相同的密鑰。
RC4算法特點:(1)、算法簡潔易于軟件實現,加密速度快,安全性比較高;(2)、密鑰長度可變,一般用256個字節。
對稱密碼的工作方式有四種:電子密碼本(ECB, electronic codebook)方式、密碼分組鏈接(CBC, cipherblock chaining)方式、密文反饋(CFB, cipher-feedback)方式、輸出反饋(OFB, output-feedback)方式。
RC4算法采用的是輸出反饋工作方式,所以可以用一個短的密鑰產生一個相對較長的密鑰序列。
OFB方式的最大的優點是消息如果發生錯誤(這里指的是消息的某一位發生了改變,而不是消息的某一位丟失),錯誤不會傳遞到產生的密鑰序列上;缺點是對插入攻擊很敏感,并且對同步的要求比較高。
RC4的執行速度相當快,它大約是分塊密碼算法DES的5倍,是3DES的15倍,且比高級加密算法AES也快很多。RC4算法簡單,實現容易。RC4的安全保證主要在于輸入密鑰的產生途徑,只要在這方面不出現漏洞,采用128bit的密鑰是非常安全的。
RC4算法加密流程:包括密鑰調度算法KSA和偽隨機子密碼生成算法PRGA兩大部分(以密鑰長度為256個字節為例)。
密鑰調度算法:首先初始化狀態矢量S,矢量S中元素的值被按升序從0到255排列,即S[0]=00, S[1]=1, …, S[255]=255.同時建立一個臨時矢量T,如果密鑰K的長度為256字節,則將K賦給T。否則,若密鑰長度為keylen字節,則將K的值賦給T的前keylen個元素,并循環重復用K的值賦給T剩下的元素,直到T的所有元素都被賦值。這些預操作可概括如下:
/*初始化*/
for i = 0 to 255 doS[i]= i;T[i]= K[i mod keylen];然后用T產生S的初始置換,從S[0]到S[255],對每個S[i],根據由T[i]確定的方案,將S[i]置換為S中的另一字節:
/*S的初始序列*/
j= 0
for i = 0 to 255 doj= (j + S[i] + T[i]) mod 256swap(S[i],S[j]);因為對S的操作僅是交換,所以惟一的改變就是順序的改變。S仍然包含從0到255的所有元素,在初始化的過程中,密鑰的主要功能是將S-box攪亂,代碼中的變量i確保S-box的每個元素都得到處理,變量j保證S-box的攪亂是隨機的。因此不同的S-box在經過偽隨機子密碼生成算法的處理后可以得到不同的子密鑰序列,并且該序列是隨機的。
偽隨機序列生成算法:矢量S一旦完成初始化,輸入密鑰就不再被使用。密鑰流的生成是從S[0]到S[255],對每個S[i],根據當前S的值,將S[i]與S中的另一字節置換。當S[255]完成置換后,操作繼續重復,從S[0]開始:
/*密鑰流的產生*/
i,j = 0;
while(true)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]偽隨機序列一旦生成,就得到子密碼sub_k,把子密鑰和明文進行異或運算,得到密文。解密過程也完全相同。加密中,只需將k的值與下一明文字節異或;相反解密中,將k的值與下一密文字節異或就可以還原出明文信息。算法描述為:
for(i = 0; i < textlength; i ++)ciphertext[i]= keystream[i] ^ plaintext[i]RC4算法存在的問題:因為RC4算法具有實現簡單,加密速度快,對硬件資源耗費低等優點,使其躋身于輕量級加密算法的行列。但是其簡單的算法結構也容易遭到破解攻擊,RC4算法的加密強度完全取決于密鑰,即偽隨機序列生成,而真正的隨機序列是不可能實現,只能實現偽隨機。這就不可避免出現密鑰的重復。RC4算法不管是加密還是解密,都只進行了異或運算,這就意味著,一旦子密鑰序列出現了重復,密文就極有可能被破解。
具體破解過程如下:若明文、密鑰是任意長的字節,可以用重合碼計數法(counting coincidence)找出密鑰長度。把密文進行各種字節的位移,并與原密文進行異或運算,統計那些相同的字節。如果位移是密鑰長度的倍數,那么超過60%的字節將是相同的;如果不是,則至多只有0.4%的字節是相同的,這叫做重合指數(index of coincidence)。找出密鑰長度倍數的最小位移,按此長度移到密文,并且和自身異或。由于明文每字節有1.3位的實際信息,因此有足夠的冗余度去確定位移的解密。對所有的密鑰,輸出密鑰流的前幾個字節不是隨機的,因此極有可能會泄露密鑰的信息。如果一個長期使用的密鑰與一個隨機數串聯產生RC4算法密鑰,那么可以通過分析大量由該密鑰加密的密文得到這個長期使用的密鑰。解決該問題的辦法是:拋棄密鑰流最初的那部分數據。
RC4is a stream cipher with variable key length.?Typically, 128 bit (16 byte) keys are used for strong encryption, butshorter insecure key sizes have been widely used due to export restrictions.
1.?RC4_set_key:sets up theB<RC4_KEY> B<key> using the B<len> bytes long key atB<data>.
2. RC4:?encrypts or decrypts the B<len>bytes of data at B<indata> using B<key> and places the result atB<outdata>.? Repeated RC4() callswith the same B<key> yield a continuous key stream. Since RC4 is a streamcipher (the input is XORed with a pseudo-random key stream to produce theoutput), decryption uses the same function calls as encryption.
以下是測試代碼:
namespace {
void RC4_Encrypt(const unsigned char* cleartext, int length, const std::string& key, unsigned char* ciphertext)
{RC4_KEY rc4key;RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());RC4(&rc4key, length, cleartext, ciphertext);
}void RC4_Decrypt(const unsigned char* ciphertext, int length, const std::string& key, unsigned char* cleartext)
{RC4_KEY rc4key;RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());RC4(&rc4key, length, ciphertext, cleartext);
}} // namespaceint test_openssl_rc4()
{const std::string cleartext = "中國北京12345$abcde%ABCDE@!!!!";const std::string key = "beijingchina1234567890ABCDEFGH!!!";char* cleartext_encode = b64_encode((const unsigned char*)cleartext.c_str(), cleartext.length());int length = strlen(cleartext_encode);fprintf(stdout, "cleartext encode length: %d\n", length);std::unique_ptr<unsigned char[]> ciphertext(new unsigned char[length]);RC4_Encrypt((const unsigned char*)cleartext_encode, length, key, ciphertext.get());std::unique_ptr<unsigned char[]> decrypt(new unsigned char[length]);RC4_Decrypt(ciphertext.get(), length, key, decrypt.get());unsigned char* ciphertext_decode = b64_decode((char*)decrypt.get(), length);fprintf(stdout, "src cleartext: %s\n", cleartext.c_str());fprintf(stdout, "genarate ciphertext: %s\n", ciphertext.get());fprintf(stdout, "dst cleartext: %s\n", ciphertext_decode);int ret = 0;if (strcmp(cleartext.c_str(), (const char*)ciphertext_decode) == 0) {fprintf(stdout, "RC4 decrypt success\n");} else {fprintf(stderr, "RC4 decrypt fail\n");ret = -1;}free(cleartext_encode);free(ciphertext_decode);return ret;
}執行結果如下:
RC4理論摘自:《RFID中輕量級加密算法及實現技術的研究》
GitHub:https://github.com/fengbingchun/OpenSSL_Test
總結
以上是生活随笔為你收集整理的对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: OpenSSL中对称加密算法DES常用函
- 下一篇: 利用CxImage实现编解码Gif图像代
