游戲協議加密及身份驗證


時間如白駒過隙,一眨眼就過去了,本打算在2月份發這篇的,結果一直誤以為2月有31日……

 

這一塊之前一直感興趣,終於在2月份爭取到機會去做這一塊的工作。前輩給我留下了一個鑒權的框架:

  1. 客戶端連接服務器
  2. 服務器將隨機數發給客戶端
  3. 客戶端用客戶端私鑰加密,發回到服務器
  4. 服務器端用客戶端公鑰解開密文,比對解開的隨機數是否與原來的一致
  5. 如果一致,則客戶端發送隨機數到服務器,服務器用服務器端私鑰加密,將密文發送到客戶端;同時,產生新的隨機數,用於稍后對會話進行rc4加密,並將這個隨機數以客戶端公鑰加密,發送到客戶端。
  6. 客戶端用服務器端公鑰解開密鑰,比對隨機數和自己發的是否相同,相同的話則用客戶端私鑰解開下一個包,取出用於rc4加密的key密文
  7. 至此,雙方身份驗證完成,會話先進行壓縮,再通過rc4算法進行加密

 

在這里,私鑰充當了一個身份的象征,只要擁有私鑰,就認為對方是授信客戶端。可能有朋友會問,如果客戶端被破解怎么辦?我覺得安全專家道哥有個觀點很好,“安全的本質是信任的問題。設計任何安全方案,最終都必須要有一個東西是「假設可以信任的」,只是看這個「可信任」的東西被攻擊成功的概率大小。如果不這么做,則做不出任何的安全方案。”所以,考慮協議安全的時候,我們只能選擇相信客戶端密鑰被安全的保管着。

 

回頭再看看這個方案,這里用到了私鑰進行加密。熟悉ssh的同學應該會聯想到其挑戰過程,ssh服務器是用客戶端公鑰對隨機數進行加密,再發送到客戶端的。公鑰加密和私鑰加密的區別是,在明文相同的情況下,公鑰加密出來的密文每次都不一樣,而私鑰加密出來的密文是每次都相同的。示例代碼可以參見: https://github.com/spin6lock/rsa_encrypt_and_decrypt_in_c 密文和明文總是一一映射,容易被碰撞攻擊,進而繞過加密過程。因此,私鑰加密多用於身份驗證,比如電子郵件的數字簽名,首先用md5對郵件明文進行信息摘要,然后用私鑰進行加密,公鑰是公開的,保證任何看到這封郵件的人都可以進行解密,獲取md5信息進行驗證,確保郵件沒有被纂改。

 

於是,我花了一周左右的時間修改了驗證流程。新的驗證流程如下:

  1. 客戶端連接服務器
  2. 服務器用客戶端公鑰加密隨機數,發給客戶端
  3. 客戶端用客戶端私鑰解密,發回服務器
  4. 服務器對比隨機數,不一樣的話就斷開連接
  5. 客戶端用服務器端公鑰加密隨機數,發送到服務器
  6. 服務器用私鑰解密,發送回客戶端
  7. 客戶端驗證通過
  8. 服務器用客戶端公鑰加密rc4會話所用密鑰,發送到客戶端
  9. 客戶端用公鑰解開,接下來在rc4加密下上傳

 

接下來,想針對手機網絡模塊的工作特點進行協議優化。由於手機受限於電量,網絡芯片工作時會有啟動,半速,全速,半速,設備待機這個速度曲線,如果能夠在應用層對包進行打包發送,能夠大大提高手機的待機時間,參見這篇開發指南。協議壓縮放在下一篇吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM