電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 27|回復(fù): 0
收起左側(cè)

用c語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的數(shù)據(jù)加解密算法

[復(fù)制鏈接]

483

主題

483

帖子

2828

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
2828
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 昨天 11:38 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
0. 前言相關(guān)文章
《C語(yǔ)言實(shí)現(xiàn)MD5,竟如此簡(jiǎn)單!》
《公鑰密碼學(xué)簡(jiǎn)介》

一、一種常見(jiàn)的網(wǎng)絡(luò)通信的加密流程關(guān)于加密的算法很多,實(shí)際實(shí)現(xiàn)過(guò)程千差萬(wàn)別,
下圖是一個(gè)常見(jiàn)的網(wǎng)絡(luò)通信加密的應(yīng)用場(chǎng)景。
密碼機(jī)的一些說(shuō)明:
客戶端服務(wù)器端都可以設(shè)置密碼機(jī)(可以是軟件、也可以是一個(gè)硬件,可以在本地也可以在某個(gè)服務(wù)器上,只要能夠產(chǎn)生密鑰即可)keygen和同步碼都會(huì)影響到密碼機(jī)生成的密鑰序列密碼機(jī)在keygen和同步碼相同的情況下,會(huì)產(chǎn)生相同的密鑰序列,加解密雙方需要記住產(chǎn)生密鑰的順序,解密多少數(shù)據(jù)就申請(qǐng)多少密鑰

如上圖所示,基于C/S架構(gòu)的服務(wù)器和客戶端通信模型,
下面以客戶端如果要發(fā)送一段加密的密文給服務(wù)器,C/S需要交互的流程。
1 服務(wù)器端發(fā)送密鑰密文首先服務(wù)器端、客戶端都保存了一個(gè)默認(rèn)的密鑰服務(wù)器端隨機(jī)生成密鑰keygen,并使用該默認(rèn)密鑰對(duì)keygen加密,生成密鑰密文客戶端可以通過(guò)命令定期請(qǐng)求該密鑰密文或者服務(wù)器定時(shí)下發(fā)客戶端收到密鑰密文后,也可以通過(guò)默認(rèn)密鑰進(jìn)行解密得到明文的keygen2. 客戶端對(duì)數(shù)據(jù)加密客戶端在發(fā)送數(shù)據(jù)之前,首先生成一個(gè)同步碼將同步碼和keygen設(shè)置給密碼機(jī),然后向密碼機(jī)申請(qǐng)一定長(zhǎng)度的密鑰將明文和密鑰通過(guò)一定的算法進(jìn)行加密(通常是異或),生成數(shù)據(jù)密文3. 客戶端發(fā)送同步碼和數(shù)據(jù)密文客戶端將數(shù)據(jù)密文和同步碼明文一起發(fā)送給服務(wù)器服務(wù)器提取出同步碼4. 服務(wù)器端接收數(shù)據(jù)并解密服務(wù)器將keygen和同步碼設(shè)置給密碼機(jī),同時(shí)申請(qǐng)一定數(shù)量的密鑰服務(wù)器根據(jù)密鑰對(duì)密文進(jìn)行解密,即得到對(duì)應(yīng)的明文因?yàn)榉⻊?wù)器和客戶端此時(shí)都使用了相同的keygen,和同步碼,所以雙方申請(qǐng)的密鑰序列一定是一樣的。
二、函數(shù)實(shí)現(xiàn)下面是一口君實(shí)現(xiàn)的加密算法的一些函數(shù)原型以及功能說(shuō)明,這些函數(shù)基本實(shí)現(xiàn)了第一節(jié)的功能。
1. 申請(qǐng)加密密鑰函數(shù)request_keyint request_key(int sync,int key_num,char key[])
功能:
向密碼機(jī)申請(qǐng)一定數(shù)量的用于加密數(shù)據(jù)的密鑰,如果不設(shè)置新的keygen,那么生成的密碼會(huì)順序產(chǎn)生下去,每次申請(qǐng)密鑰都會(huì)記錄上次生成的密鑰的偏移,下次在申請(qǐng)的時(shí)候,都會(huì)從上一位置繼續(xù)分配密鑰
參數(shù):
sync:同步碼,密碼機(jī)依據(jù)此同步產(chǎn)生隨機(jī)序列的密鑰
key_num:申請(qǐng)的密鑰個(gè)數(shù)
key:申請(qǐng)的密鑰存儲(chǔ)的緩存
返回值:
實(shí)際返回密鑰個(gè)數(shù)
2. 設(shè)置密鑰序列函數(shù)set_keygenvoid set_keygen(int key)
功能:
向密碼機(jī)設(shè)置keygen,設(shè)置后會(huì)影響產(chǎn)生的隨機(jī)密鑰序列
參數(shù):
key:密鑰
返回值:
無(wú)
3. 產(chǎn)生隨機(jī)數(shù)born_seedint born_seed(int sync,int key)
功能:
根據(jù)同步碼和keygen生成隨機(jī)密鑰種子
參數(shù):
    sync:同步碼
key:密鑰
返回值:
種子
4. 重置keygen reset_keygen()void reset_keygen()
功能:
重置keygen,會(huì)影響生成的隨機(jī)數(shù)序列
三、測(cè)試代碼實(shí)例最終文件如下:
key.c  key.h  main.c
示例1 檢測(cè)產(chǎn)生的隨機(jī)序列int main(int argc, char *argv[])
{
int i;
unsigned int len;
int j, r, key_num;
unsigned int sync = 0;
unsigned char key[MAX_KEY_REQUEST];

key_num = 10;
printf("
--------------采用默認(rèn)keygen 同步碼=0 產(chǎn)生密文----------------
");
reset_keygen();
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰0-9:",key,len);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰10-19:",key,len);
printf("
--------------采用keygen=1234 同步碼=0 產(chǎn)生密文----------------
");
set_keygen(1234);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰0-9:",key,len);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰10-19:",key,len);
}
執(zhí)行結(jié)果:
--------------采用默認(rèn)keygen 同步碼=0 產(chǎn)生密文----------------
密鑰0-9: ----[10]
a5 52 c8 14 5d f7 46 5b 89 42
密鑰10-19: ----[10]
38 69 6f a6 08 d2 69 39 cd 29
--------------采用keygen=1234 同步碼=0 產(chǎn)生密文----------------
密鑰0-9: ----[10]
0e 83 0b 73 ec f5 4b 4a 74 35
密鑰10-19: ----[10]
e7 f1 06 41 c8 6b aa df 0c 3d
可以看到采用不同的keygen產(chǎn)生的隨機(jī)序列是不一樣的。
如果設(shè)置不同的同步碼,仍然序列還會(huì)不一樣。
示例2 用默認(rèn)keygen,加解密char data0[10]={
0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,
};
int main(int argc, char *argv[])
{
int i;
unsigned int len;
int j, r, key_num;
unsigned int sync = 0;
unsigned char key[MAX_KEY_REQUEST];
char buf[120]={0};
key_num = 10;
printf("
--------------采用默認(rèn)keygen開(kāi)始加密----------------
");
reset_keygen();
print_array("
明文:",data0,key_num);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰:",key,len);
for(i=0;i"
密文:",buf,len);

printf("
--------------------開(kāi)始解密--------------------
");
reset_keygen();
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);

for(i=0;i"
明文:",buf,len);
}
測(cè)試結(jié)果
--------------采用默認(rèn)keygen開(kāi)始加密----------------
明文: ----[10]
01 02 03 04 05 06 07 08 09 10
密鑰: ----[10]
a5 52 c8 14 5d f7 46 5b 89 42
密文: ----[10]
a4 50 cb 10 58 f1 41 53 80 52
--------------------開(kāi)始解密--------------------
明文: ----[10]
01 02 03 04 05 06 07 08 09 10
示例3 用不同的keygen和同步碼加解密int main(int argc, char *argv[])
{
int i;
unsigned int len;
int j, r, key_num;
unsigned int sync = 0;
unsigned char key[MAX_KEY_REQUEST];
char buf[120]={0};
unsigned int mykeygen;

if (argc != 4) {
  fprintf(stderr, "Usage: %s   
", argv[0]);
  exit(EXIT_FAILURE);
}
sync = atoi(argv[1]);
key_num = atoi(argv[2]);
mykeygen = atoi(argv[3]);
printf("
--------------采用自定義的keygen、同步碼開(kāi)始加密----------------
");
set_keygen(mykeygen);
print_array("
明文:",data0,key_num);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
print_array("密鑰:",key,len);
for(i=0;i"
密文:",buf,len);

printf("
--------------------開(kāi)始解密--------------------
");
set_keygen(mykeygen);
memset(key,0,sizeof(key));
len = request_key(sync,key_num,key);
for(i=0;i"
明文:",buf,len);
exit(EXIT_SUCCESS);
}
執(zhí)行結(jié)果如下:
--------------采用自定義的keygen、同步碼開(kāi)始加密----------------
明文: ----[10]
01 02 03 04 05 06 07 08 09 10
密鑰: ----[10]
53 00 29 cd 27 eb cc 80 1a d7
密文: ----[10]
52 02 2a c9 22 ed cb 88 13 c7
--------------------開(kāi)始解密--------------------
明文: ----[10]
01 02 03 04 05 06 07 08 09 10
可見(jiàn)我們的確實(shí)現(xiàn)了數(shù)據(jù)的加密和解密。
四、數(shù)據(jù)加密的實(shí)際使用假定我們使用上述實(shí)例代碼,把對(duì)應(yīng)的功能移植到C/S兩端,
那么一次完整的數(shù)據(jù)加密以及數(shù)據(jù)的傳輸參考流程如下:

記住一點(diǎn),只要雙方設(shè)置相同的keygen和同步碼,那么密碼機(jī)吐出來(lái)的密鑰就是相同序列,
客戶端發(fā)送每發(fā)送一個(gè)報(bào)文,就把自己的明文同步碼一起發(fā)送給服務(wù)器,
服務(wù)器根據(jù)提前發(fā)送給客戶端的keygen和同步碼就可以實(shí)現(xiàn)解密操作,
雖然你可以看到明文的同步碼,
但是還需要破解密碼機(jī)算法、服務(wù)器下發(fā)的keygen密文。
五、 原理實(shí)現(xiàn)加密算法的主要問(wèn)題是如何產(chǎn)生隨機(jī)序列作為密鑰。
本例是借用庫(kù)函數(shù)rand() 原型如下:
#include
int rand(void);
函數(shù)rand() 雖然可以產(chǎn)生隨機(jī)序列,但是每次產(chǎn)生的序列其實(shí)順序是一樣的。
#include
main()
{
int i = 0;
for(i=0;i10;i++)
{
  printf("%d ",rand());
}
putchar('
');
}
運(yùn)行結(jié)果如下:
peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
要想每次都產(chǎn)生不一樣的隨機(jī)序列應(yīng)該怎么辦呢?需要借助srand()函數(shù)
void srand(unsigned int seed);
只需要通過(guò)該函數(shù)設(shè)置一個(gè)種子,那么產(chǎn)生的序列,就會(huì)完全不一樣,
通常我們用time()返回值作為種子,
在此我們隨便寫(xiě)入幾個(gè)數(shù)據(jù),來(lái)測(cè)試下該函數(shù)
#include
main()
{
int i = 0;
srand(111);
for(i=0;i10;i++)
{
  printf("%d ",rand());
}
putchar('
');
srand(1111);
for(i=0;i10;i++)
{
  printf("%d ",rand());
}
putchar('
');
}
執(zhí)行結(jié)果如下:
peng@peng-virtual-machine:/mnt/hgfs/peng/rand/code$ ./a.out
1629905861 708017477 1225010071 14444113 324837614 2112273117 1166384513 1539134273 1883039818 779189906
1383711924 882432674 1555165704 1334863495 1474679554 676796645 154721979 534868285 1892754119 100411878
可見(jiàn)輸入不同的種子就會(huì)產(chǎn)生不同的序列。
函數(shù)原型如下:

本例原理比較簡(jiǎn)單,沒(méi)有考慮太復(fù)雜的應(yīng)用(比如多路密鑰的管理)和數(shù)據(jù)安全性,
只闡述加解密的流程,僅作為學(xué)習(xí)理解加解密流程用,此種加密算法屬于對(duì)稱(chēng)加密,相對(duì)比較簡(jiǎn)單,還是比較容易破解。
目前市場(chǎng)上都是由專(zhuān)業(yè)的公司和團(tuán)隊(duì)實(shí)現(xiàn)加解密功能。
一口君之前曾寫(xiě)過(guò)聊天室的一個(gè)小項(xiàng)目,
《聊天室》
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-多線程服務(wù)器模型-1
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-多線程服務(wù)器一個(gè)很隱晦的錯(cuò)誤-2   
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-實(shí)現(xiàn)聊天室的登錄、注冊(cè)功能-3
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-增加公聊、私聊-4  必看
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-增加數(shù)據(jù)庫(kù)sqlite功能-5 必看
  • 從0實(shí)現(xiàn)基于Linux socket聊天室-增加數(shù)據(jù)加密功能-6
    [/ol]彭老師基于該加密機(jī)制,將聊天室所有客戶端與服務(wù)器所有交互數(shù)據(jù)進(jìn)行加密處理,有興趣的老鐵可以下載學(xué)習(xí)下。
    本文完整代碼下載地址:
    鏈接:https://pan.baidu.com/s/1VvGNlNGEUWWZHQZ1_gYU7A 提取碼:o9se
    后臺(tái)回復(fù):數(shù)據(jù)加密,即可獲得全部源碼
  • 發(fā)表回復(fù)

    本版積分規(guī)則

    關(guān)閉

    站長(zhǎng)推薦上一條 /1 下一條


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表