使用 JWT(JSON Web Tokens) 的安全性問題

  • 2211
  • 0
  • 2017-09-15

認識 JWT 最好的方式就是到官網查看介紹 https://jwt.io/introduction/

 

JSON Web Tokens 目前在以下兩種情景很有用:

認證:例如從登入時取得 Token 儲存在 local session,或是提供某些服務核發 Token,就能將該 Token 放在 Http Headers  一起發送到 Server 端做認證。

資訊交換:一般傳遞訊息有個問題,就是你無法知道這訊息是否被竄改過,透過簽章後傳送JWT給對方,對方也用相同密鑰進行簽章確定訊息沒被竄改過,內容另外可搭配非對稱式加密法加密。

 

為什麼 JWT 裡面建議不要放重要的資訊?

例如:密碼、身分證、還是私密的資料等...

 

因為最單純的 JWT 是由3個部分組成,Header、Payload、Signature,其中 Header、Payload是任何人拿到 Token 都能直接知道裡面內容的,而 Signature 是負責對 Header + "." + Payload 進行簽章的結果,

例如你產生的一組 Token: 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

將中間的 payload 用 base64 解碼回來,

var payload = Encoding.ASCII.GetString(Convert.FromBase64String("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"));

Console.WriteLine(payload);

就能看到是什麼

{"sub":"1234567890","name":"John Doe","admin":true}

 

所以很重要的觀念是,JWT原本只是能驗證 Client 傳來的 Token,是不是用 Server 密鑰所核發的,密鑰也只是用於簽章,並不會對你的 JWT Header 與 Payload 做任何加密,只是用 Base64 進行編碼,方便用字串呈現出來。

 

雖然你也能自己先將 Payload 加密後,在做簽章,JWT 的字串會變長一點,額外多一點CPU時間做加解密,只要安全性與效能評估過,要這樣用也可以啦...