2025年9月7日 星期日

Access Token正確流程及建議

正確的流程應該是這樣:

目標:讓 Server 能確認 Client 身分 + 發給 access token,並用私鑰做後續身份驗證


1. Client 生成公私鑰對

  • Client 裝置內部(或 Secure Element)產生金鑰對

    • 私鑰保留在本地(永不離開)

    • 公鑰送給 Server 註冊(一次性或定期)


 2. Client 向 Server 請求 access token(附上公鑰簽章)

POST /auth/token Content-Type: application/json { "device_id": "ABC123456", "timestamp": 1694175600, "signature": "<用私鑰對 device_id + timestamp 簽章>", "public_key": "base64(pubkey)" // 如果是第一次註冊 }

 Server 驗證:

  • 比對這個 device_id 是否對應這組公鑰

  • 用公鑰驗證簽章確保是該裝置發的請求


 3. Server 發出 access token(不含私鑰)

{ "access_token": "<JWT with claims>", "expires_in": 3600 }

Token payload 可能會長這樣(例如 JWT):

{ "sub": "ABC123456", "iat": 1694175600, "exp": 1694179200, "scope": "read:sensor write:status" }

這個 Token 是「身份憑證」,用於呼叫其他 API 時帶上。


 4. Client 使用 access token 呼叫 API(必要時用私鑰簽名)

範例:

POST /data/upload Authorization: Bearer <access_token> Signature: <用私鑰對 payload 簽章> { "temperature": 26.5, "timestamp": 1694175699 }

Server:

  • 先驗證 access token 有效(JWT 解析)

  • 再用對應的「公鑰」來驗證簽章

  • 確保是那台設備傳來的資料、未被冒充


 為什麼這樣設計?

問題回答
誰持有私鑰?僅 Client 持有,且永不外傳
公鑰做什麼?Server 儲存並驗證簽章用
Token 怎麼驗證身分?Server 先驗 JWT,再驗裝置簽章
為何不在 token 裡放私鑰?會造成大規模洩漏風險,一台被破解,所有都可能被仿冒

額外安全建議

  • ✅ 每個 Client 裝置用獨立的私鑰

  • ✅ 儲存在 Secure Element(如 ATECC608A)

  • ✅ 使用短效的 access token + 長效的 refresh token

  • ✅ 避免設備共用公私鑰對(共用=一破全破)

沒有留言:

張貼留言