之前寫過一篇關于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