天天看點

網際網路安全性問題

網際網路安全性問題

       談到網際網路安全,會想起中間人攻擊,DNS劫持,代理伺服器等,對于這麼多的危險,怎麼保證我們的系統真的足夠安全呢?

一個有效的方法:End to End Encryption(端對端加密)

    怎麼去了解端對端加密呢?核心有如下兩點:

  • 用戶端和服務端交換期間,資料是加密的
  • 既然加密,就用到加密的key,每個用戶端使用到的加密key都應該不一樣

解決方法:

  1. 模拟Https的加密流程,生成一個sessionKey,用于加密互動時的資料
  2. 這種方式經過駭客的評估,确實有效地防止被攻擊

流程

  1. 前端請求後端拿到public key
  2. 前端生成一個16位的cKey(UUID),用public key加密,傳給後端
  3. 後端拿到加密内容後,用private key解密,拿到cKey
  4. 後端又生成一個16位的sKey(UUID),然後兩個key一起做異或,生成一個sessionKey
  5. 将cKey,sKey,sessionKey儲存到DB,而且資料要進行加密的,并且有一個sessionId(UUID)作為唯一辨別,sessionId不用加密
  6. 然後用cKey加密sKey和sessionId傳回給前端,前端用自己的cKey解密,拿到sKey
  7. 然後前端做一次異或,生成一個sessionKey儲存在App的runtime
  8. 每次請求的參數,以userId=1&name=AA這樣的一個字元串用sessionKey進行加密,然後sessionId放在請求的header中,
  9. 後端拿到資料後,先根據sessionId找到資料庫對應的sessionKey 和 IV,然後解密這兩個值,然後再用這另個值來解密encData。

問題一:End to End Encryption 過程中,需要拿到後端的公匙,可不可以再改進?

問題關鍵:

  1. 現在服務端的public key、private key是固定的,放在伺服器的一個安全機器上,能不能将其改成可變的?

解決思路:

  1. 每次使用者需要生成sessionKey的時候,先用deviceId作為key,在redis中查查,看有沒有對應吖pubic key、private key,如果有就拿出來用,如果沒有就重新生成一對。
  2. 因為deviceId每台機器都不一樣,是以生成的public key、private key是不一樣的。

問題二:即使做好了加密,如果被人攔截到請求的所有資料,怕不怕被用來重複送出

問題關鍵:

  1. 這種敏感的請求,應該有個逾時時間來記錄什麼時候無效
  2. 同時,不能重複使用

解決思路:

  1. 用戶端發起請求時,生成一個timeStemp,這是目前送出的時間。
  2. 服務端拿到請求後,首先檢查timeStemp,跟目前時間比較,看是否超過5分鐘,如果超過就是無效的,如果不超過就是有效的。
  3. 那在這5分鐘的時間内,怎麼保證不會被重複請求呢?
  4. 使用redis做分布式鎖,設定一個clientRef(16位UUID)作為key,在第一次請求時,看拿不拿得到redis的一個key。
  5. 如果拿得到,證明已經執行過了,可以直接抛異常。
  6. 如果拿不到,證明還沒有執行過,那就執行請求。
  7. key的逾時時間是5分鐘,5分鐘後自動删除,這樣就可以補充這5分鐘的空隙了。

問題三:如果跟第三方系統互動,要防止請求資料被中間人篡改了,怎麼辦?

關鍵問題:

  1. 怎麼檢查被篡改過?數字簽名

解決思路:

  1. 先跟第三方約定數字簽名的加密算法,如:SHA256
  2. 第三方請求過來時,生成timeStamp,clientRef,以及request json body一起組成一串字元串,用算法進行加密,名字叫signature(數字簽名)
  3. 第三方請求中,header中,放timeStamp,clientRef,signature
  4. 我們服務端收到請求後,将timeStemp,clientRef,request json body,以相同的規則,組成字元串,再用算法進行加密
  5. 加密後的值和signature比較,看是否相等
  6. 如果相等就沒問題,不相等就抛異常

如何改進:

  1. 可以從加密算法中改進,可以用Hash,對稱加密,非對稱加密(事先要把public key的證書給第三方)
  2. timeStamp,clientRef,signature,組成字元串的規則可以跟第三方約定好,保證不會那麼容易被猜到