天天看點

手把手教你如何實作一個簡單的資料加密算法

之前寫過一篇關于MD5摘要算法的文章,很多老鐵說能否出一篇關于加密的文章嗎?

《C語言實作MD5,竟如此簡單!》

一口君的字典裡沒有"不行"這兩個字!必須安排!

關于加密的一些基本概念,大家可以參考下面這一篇文章:

《公鑰密碼學簡介》

本文,一口君帶着大家自己實作一個簡單但也很實用的加密方法,

讓大家了解實際項目開發中資料加密的流程。

關于加密的算法很多,實際實作過程千差萬别,

下圖是一個常見的網絡通信加密的應用場景。

密碼機的一些說明:

用戶端伺服器端都可以設定密碼機(可以是軟體、也可以是一個硬體,隻要能夠産生密鑰即可)

keygen和同步碼都會影響到密碼機生成的密鑰序列

密碼機在keygen和同步碼相同的情況下,會産生相同的密鑰序列,加解密雙方需要記住産生密鑰的順序,解密多少資料就申請多少密鑰

手把手教你如何實作一個簡單的資料加密算法

如上圖所示,基于C/S架構的伺服器和用戶端通信模型,

下面以用戶端如果要發送一段加密的密文給伺服器,C/S需要互動的流程。

首先伺服器端、用戶端都儲存了一個預設的密鑰

伺服器端随機生成密鑰keygen,并使用該預設密鑰對keygen加密,生成密鑰密文

用戶端可以通過指令定期請求該密鑰密文或者伺服器定時下發

用戶端收到密鑰密文後,也可以通過預設密鑰進行解密得到明文的keygen

用戶端在發送資料之前,首先生成一個同步碼

将同步碼和keygen設定給密碼機,然後向密碼機申請一定長度的密鑰

将明文和密鑰通過一定的算法進行加密(通常是異或),生成資料密文

用戶端将資料密文和同步碼明文一起發送給伺服器

伺服器提取出同步碼

伺服器将keygen和同步碼設定給密碼機,同時申請一定數量的密鑰

伺服器根據密鑰對密文進行解密,即得到對應的明文

因為伺服器和用戶端此時都使用了相同的keygen,和同步碼,是以雙方申請的密鑰序列一定是一樣的。

下面是一口君實作的加密算法的一些函數原型以及功能說明,這些函數基本實作了第一節的功能。

最終檔案如下:

執行結果:

可以看到采用不同的keygen産生的随機序列是不一樣的。

如果設定不同的同步碼,仍然序列還會不一樣。

測試結果

執行結果如下:

可見我們的确實作了資料的加密和解密。

假定我們使用上述執行個體代碼,把對應的功能移植到C/S兩端,

那麼一次完整的資料加密以及資料的傳輸參考流程如下:

手把手教你如何實作一個簡單的資料加密算法

記住一點,隻要雙方設定相同的keygen和同步碼,那麼密碼機吐出來的密鑰就是相同序列,

用戶端發送每發送一個封包,就把自己的明文同步碼一起發送給伺服器,

伺服器根據提前發送給用戶端的keygen和同步碼就可以實作解密操作,

雖然你可以看到明文的同步碼,

但是還需要破解密碼機算法、伺服器下發的keygen密文。

實作加密算法的主要問題是如何産生随機序列作為密鑰。

本例是借用庫函數rand()

原型如下:

函數rand() 雖然可以産生随機序列,但是每次産生的序列其實順序是一樣的。

運作結果如下:

要想每次都産生不一樣的随機序列應該怎麼辦呢?

需要借助srand()函數

隻需要通過該函數設定一個種子,那麼産生的序列,就會完全不一樣,

通常我們用time()傳回值作為種子,

在此我們随便寫入幾個資料,來測試下該函數

可見輸入不同的種子就會産生不同的序列。

函數原型如下:

手把手教你如何實作一個簡單的資料加密算法

本例原理比較簡單,沒有考慮太複雜的應用(比如多路密鑰的管理)和資料安全性,

隻闡述加解密的流程,僅作為學習了解加解密流程用,此種加密算法屬于對稱加密,相對比較簡單,還是比較容易破解。

目前市場上都是由專業的公司和團隊實作加解密功能。

一口君之前曾寫過聊天室的一個小項目,

《從0實作基于Linux socket聊天室》

後面一口君會基于該加密機制,将聊天室所有用戶端與伺服器所有互動資料進行加密處理,請大家持續關注:一口Linux。

本文完整代碼下載下傳位址:

連結:https://pan.baidu.com/s/1VvGNlNGEUWWZHQZ1_gYU7A 提取碼:o9se

背景回複:資料加密,即可獲得全部源碼

歡迎關注公衆号:一口Linux

繼續閱讀