2017-04-19 74 views
5

我目前正在使用PHP學習JWT實現,並希望爲我的RESTful應用程序使用JWT令牌而不是會話。在智威湯遜有效負載中存儲敏感數據安全嗎?

在簽名製作的,我在這裏,我們只是使用Base64有效載荷做這樣

token = base64Header + '.' + base64Payload + '.' + signature 

東西。如果我粘貼https://jwt.io/#debugger這樣的站點,Payload將被解密(即使簽名是錯誤的)。

我的問題,

  1. 僅用於發送數據時驗證與服務器簽名JWT?
  2. 是否不安全以保持敏感數據在有效載荷中?
  3. 如果不安全,有什麼辦法來保證有效負載?

下面是示例代碼我寫

<?php 
    $headers = base64_encode(json_encode([ 
     "typ" => "JWT", 
     "alg" => "HS256" 
    ])); 
    $claims = base64_encode(json_encode([ 
     "sub" => "1234567890", 
     "name" => "John Doe", 
     "admin" => true, 
     "jti" => "870a3de5-ea7b-4062-abef-11180e530f5a", 
     "iat" => 1492603378, 
     "exp" => 1492606978 
    ])); 
    $payload = $headers.".".$claims; 
    $signature = base64_encode(hash_hmac("sha256", $payload, 'secret', true)); 
    $encodedJWT = $payload.".".$signature; 
    // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6Ijg3MGEzZGU1LWVhN2ItNDA2Mi1hYmVmLTExMTgwZTUzMGY1YSIsImlhdCI6MTQ5MjYwMzM3OCwiZXhwIjoxNDkyNjA2OTc4fQ.nvw-bAUgr7H_xr3q8_Yz8rCNtMohtn2YlCmcLoLBWlc 
+0

請在downvoting之前提供意見。如果有什麼不對,我會更新我的問題:) –

+0

嗨,根據我參加JWT會議的信息,敏感數據應該保留在數據庫中,令牌本身應該只包含快速識別所需的信息,而不是授權。 – Auris

+0

我們應該在upvoting之前提供意見嗎? - :)原因downvote評論是罕見的是becasuse所以主持人建議不要偶爾報復downvoting。 – zaph

回答

5

如果我像https://jwt.io/#debugger網站粘貼,有效載荷就會被解密(即使簽名是錯誤的)。

由於第三方沒有密鑰,因此無法驗證簽名。 有效負載不被解密 - 它被解碼。

理想情況下,您應該而不是將敏感數據存儲在有效內容中,因爲有效內容僅爲base64編碼且未加密。這意味着任何持有令牌的人都可以通過base64解碼來查看有效載荷的內容。

如果您在Web瀏覽器的本地存儲中擁有令牌,並且您的站點存在XSS漏洞,則竊取該令牌會變得微不足道。攻擊者擁有一個有效的JWT已經夠糟了(無論如何這個JWT很快就會過期),但是如果它包含敏感數據,那麼你真的很麻煩。想象一下,必須通知您網站上的所有用戶,他們現在必須改變有關他們自己的敏感數據的各種位,因爲可能存在大規模的妥協。

保持JWT輕量級。存儲用戶ID,他們的角色/授予系統。如果您覺得您需要將敏感數據添加到有效負載中,請嘗試並重新考慮您的解決方案。

1

據我所知,你試圖擁有一個完整的stateless服務器,所以你想要在令牌中存儲敏感數據。

但是你的服務器不能完全無狀態。由於註銷功能,您必須有黑名單白名單以使令牌無效。因此,在每個請求中,您必須觸摸數據庫。如果您沒有黑名單白名單,即使用戶註銷,令牌仍然有效。

因此,最好從數據庫中獲取敏感數據,因爲每次請求都應該觸摸你的數據庫。

+1

如你所說,擁有一個黑名單或白名單使得它不如無國籍。所以應該避免。只有短命令令牌會更好,所以沒有「註銷」動作。註銷操作只是客戶端刪除令牌。 – jfadich

+0

短暫到期並不能解決問題。特別是在移動應用程序中,至少您必須擁有用戶想要保持登錄的選項。(在現代應用程序中,用戶永遠不會註銷)因此,您有某種令牌根本不包含'exp' 。如果用戶想要註銷,該怎麼辦?令牌將是有效的! –

+2

讓一個沒有'exp'的令牌是非常糟糕的做法。擁有認證令牌和刷新令牌會更好(這是大多數谷歌產品的工作原理)。身份驗證令牌隨每個請求一起發送,以授權請求,但僅在短時間內有效(例如30分鐘)。刷新令牌用於在其到期後獲取新的授權令牌。刷新標記應該仍然有效,但可能會更長(例如2周),並且可以自行刷新。要註銷,客戶端將刪除這兩個令牌。這可以讓你的用戶總是安全地登錄(只需保持新鮮的令牌的祕密) – jfadich

1
  1. JWT僅用於在發送數據時驗證服務器簽名嗎?

不,不僅有簽署的JWT (JWS - RFC 7515),還有加密的JWT (JWE - RFC 7516)

  1. 對於Payload中的敏感數據是否不安全?

當JWT加密時,您可以安全地共享敏感數據(除非算法或密鑰被泄露)。

但在你的例子中,我看不到任何敏感數據,因此我想知道在你的情況下使用JWE是否真的很重要。 我強烈建議你到read this blog post關於智威湯遜和會議,以及爲什麼你不應該使用它們(也看看that part 2)。

如果你真的想使用JWE,那麼我寫了a PHP library,它已經能夠加載和創建任何種類的Jose(JWS/JWE),並支持幾乎所有的算法,從RFC 7518開箱即用。 可能存在其他庫,但沒有引用列表(https://jwt.io/僅列出JWS實現)。