RC4加密出現空字元

2021-06-09 21:02:54 字數 3397 閱讀 7330

rc4加密出現空字元

最近做的競賽用了rc4加密,網上copy的**(沒興趣自己研究密碼學,而且我沒有數學天分),整到mfc程式中,出了點小問題。

先上**(做了點小修改)

#include

#include

/*-----------------------初始化函式定義--------------------------*/

void rc4_init(unsigned char *s, unsigned char *key, unsigned long len)  // s為s-box的位址,key是金鑰字串位址,len是金鑰的長度

;    unsigned char tmp = 0;

for(i=0;i<256;i++)

for (i=0; i<256; i++)

}/*-----------------------加解密函式定義--------------------------*/

void rc4_crypt(unsigned char *s, unsigned char *data, unsigned long len)  // s是s-box的位址,data是需要加(解)密字串位址

}/*-------------------------主函式-----------------------------*/

void main()

; //s-box

char key[256];

char pdata[512];

unsigned long len;

printf("input message:");

gets(pdata);

len=strlen(pdata);

printf("input key:");

gets(key);

rc4_init(s,(unsigned char *)key,strlen(key));

//  呼叫初始化函式用金鑰對s-box進行初始化

rc4_crypt(s,(unsigned char *)pdata,len);

//  加密

printf("cipher text: \"%s\"\n\n",pdata);

//  輸出密文

rc4_init(s,(unsigned char *)key, strlen(key));

//  呼叫初始化函式對s-box進行初始化

rc4_crypt(s,(unsigned char *)pdata,len);

//  解密

printf("plain text: \"%s\"\n\n",pdata);

//  輸出明文

}你可以試驗一下,輸入明文superman(注意大小寫),輸入金鑰123。你發現了什麼!密文是"",可是再次解密得到的明文卻仍然是

"superman"。當時我就震驚了。這是為什麼呢?除錯發現是在明文加密時,也就是第一次進入rc4_crypt函式時,

for(k=0;k

經過一系列變換,s[t]是字元's',而明文的第乙個字元data[0]剛好是's',這個時候要進行異或(data[k] ^= s[t])操作,就導致data[0]的值變為0,也就是'\0',在後面輸出密文的時候,printf函式把'\0'作為字串結尾,於是輸出的就是空的了。

但是解密為什麼又能成功呢?因為解密的時候rc4_crypt函式是分別對pdata的每個元素解密的,pdata[0]不管是什麼,它都給你解密出來。另外在對乙個字串進行加密的時候,i、j變數都是在變的,所以你輸入"nsuperman",這裡的's'就不會變成'\0'了。

既然解密出來是對的,那還有什麼問題呢?當我把它用到mfc程式中就出問題了。我的mfc程式裡用的都是cstring型別的,cstring很方便,我很喜歡,但是cstring也是把'\0'當做字串結尾的,於是我有些字串加密出來就會資訊不全,甚至向上面的"superman"一樣,完全給整沒了。

那該怎麼辦呢?我就用了個最簡單的方法:遇到s[t]和data[k]相同的情況,那個字元直接不加密。just like that:

if( data[k] != s[t] )

data[k] ^= s[t];

不管你喜不喜歡,我還是這樣做了。我又懶又笨,不喜歡搞得太複雜。你有什麼好的方法,歡迎交流。

具體的mfc**,不管你需不需要,我也給上了吧。rc4源**用s[256]、key[256]、pdata[512],我也就用這些了,懶得去搞個純mfc版本的rc4。

void crc4dlg::onencrypt()//用來加密的button的訊息響應函式

;    char pdata[512] = ;

int nlength = m_plain.getlength();//這裡m_plain是與乙個editbox相關聯的cstring型別的成員變數

for(int i = 0 ; i < nlength ; i++ )//nlength儲存了m_plain的字元數

char key[256] = ;//ourkey 是個巨集:#define ourkey "123" // 你想要的金鑰

rc4_init(s,(unsigned char *)key,strlen(key));//初始化s-box

rc4_crypt(s,(unsigned char *)pdata,strlen(pdata));//加密

m_cryption = pdata;//m_cryption也是和乙個editbox相關聯的cstring型別的變數,用來儲存密文

updatedata(false);

}void crc4dlg::ondecrypt()//用來解密的button的訊息響應函式

;    char pdata[512] = ;

int nlength;

length = m_cryption.getlength();

for( i = 0 ; i < nlength ; i++ )

char key[256] = ;

rc4_init(s,(unsigned char *)key,strlen(key));//初始化s-box

rc4_crypt(s,(unsigned char *)pdata,strlen(pdata));//解密

m_decryption = pdata;//m_decryption是個和editbox相關的cstring類的變數,存放解密出的明文

updatedata(false);

}還有別忘了在rc4_crypt中處理會出現'\0'的那段**,否則加密後密文就沒了。

這裡還有個問題,你在加密的編輯框輸入"superman",按加密按鈕,密文的編輯框上會顯示密文,當你按下解密按鈕的時候,出現在解密出的明文的編輯框上的"superma",少了個字元,經常會出現這種情況。這可能是updatedata從編輯框交換資料時候出的問題。這個問題我沒有去研究,求大神指導。另外如果把密文存到乙個檔案中,再讀取這個檔案中的密文進行解密,貌似一點問題都沒有。

RC4加密隨筆

1.原理 1.1 初始化金鑰 根據輸入的金鑰key,使用金鑰排程演算法ksa生成乙個256位元組的sbox。1.2 再通過偽隨機數生成演算法 prga 得到金鑰流 keystream 1.3 加密 金鑰流與明文進行異或運算得到密文 1.4 解密 密文與金鑰流進行異或運算得到明文 2.金鑰排程演算法k...

RC4加密 解密

建立rc4crypto類 using system using system.collections.generic using system.linq using system.text using system.web namespace rc.web.utility 有參構造器 密碼 publ...

RC4加密演算法

rc4於1987年提出,和des演算法一樣,是一種對稱加密演算法,也就是說使用的金鑰為單鑰 或稱為私鑰 但不同於des的是,rc4不是對明文進行分組處理,而是位元組流的方式依次加密明文中的每乙個位元組,解密的時候也是依次對密文中的每乙個位元組進行解密。rc4演算法的特點是演算法簡單,執行速度快,而且...