分布式数字签名令牌TokenProvider
在分布式系統(tǒng)中,令牌簽發(fā)系統(tǒng)往往需要跟令牌應用系統(tǒng)分離,并且應用系統(tǒng)可以獨立驗證令牌,無需請求簽發(fā)系統(tǒng)接口。
數(shù)字簽名令牌屬于發(fā)明專利《基于令牌協(xié)議的令牌組網(wǎng)構(gòu)建方法》(已授權(quán)專利號201510213377.X)的一部分,設計于2013年!
在物聯(lián)網(wǎng)平臺中,設備驗證服務器以及設備接入服務器是分開的,并且有很多接入服務器。驗證服務器簽發(fā)的令牌,可用于多臺接入服務器。
功能特性
主要功能特性:
DSA數(shù)字簽名提供安全,默認1024位,最高4096位;
應用系統(tǒng)獨立驗證令牌,無需請求簽發(fā)系統(tǒng)的接口;
令牌短小,一般在80字符以內(nèi),降低嵌入式設備的內(nèi)存消耗以及網(wǎng)絡傳輸量;
支持物聯(lián)網(wǎng)設備使用,常見幾十塊錢的民用設備或更高的工業(yè)設備;
應用場景
工作流程
物聯(lián)網(wǎng)設備聯(lián)網(wǎng)后,首先前往驗證系統(tǒng)進行設備有效性驗證,獲取令牌,即可攜帶令牌訪問各應用服務器。
令牌具有有效期,一般2小時過期。應用服務器遇到過期令牌時,應該拒絕提供服務,設備將再次訪問驗證系統(tǒng)獲取新令牌。
對于長連接通信的物聯(lián)網(wǎng)設備,僅在連接建立的時候使用一次令牌驗證身份,后續(xù)通信無需再次驗證令牌,即使超過了有效期。除非網(wǎng)絡中斷需要重新建立TCP長連接。
示例詳解
Nuget引用包 NewLife.Core
源碼:https://github.com/NewLifeX/X/blob/master/NewLife.Core/Web/TokenProvider.cs
生成密鑰
ReadKey方法用于讀取文件密鑰,第二個參數(shù)可指定當密鑰文件不存在時創(chuàng)建一組公鑰私鑰。
var prv = new TokenProvider(); // 加載或生成密鑰 var rs = prv.ReadKey("keys/test.prvkey", true); Assert.True(rs); Assert.True(File.Exists("keys/test.prvkey".GetFullPath())); Assert.True(File.Exists("keys/test.pubkey".GetFullPath())); Assert.NotEmpty(prv.Key);私鑰由驗證服務器自己保存,公鑰分發(fā)到各應用服務器中。
簽發(fā)令牌
為了讓令牌足夠短小,數(shù)據(jù)部分只有一個user字符串和有效期時間戳,user可以是用戶名,也可以是設備編號。魔方OAuthServer使用了TokenProvider,平穩(wěn)工作多年。
var prv = new TokenProvider(); // 生成令牌 var user = Rand.NextString(8); var time = DateTime.Now.AddHours(2); var token = prv.Encode(user, time); Assert.NotEmpty(token); var data = token.Substring(null, ".").ToBase64().ToStr(); Assert.Equal($"{user},{time.ToInt()}", data);驗證令牌
TryDecode用于解碼令牌,并返回驗證是否成功
// 解碼令牌 var prv2 = new TokenProvider(); prv2.ReadKey("keys/test.pubkey", false); var rs2 = prv2.TryDecode(token, out var user2, out var time2); Assert.True(rs2); Assert.Equal(user, user2); Assert.Equal(time.Trim(), time2.Trim());令牌防篡改
故意破壞令牌,把數(shù)據(jù)部分用戶名改為其它賬號,時間戳和簽名不變,得到的新令牌無法通過應用服務器公鑰的簽名驗證。這就讓令牌具有了防篡改能力。
// 破壞數(shù)據(jù) token = $"Stone,{time.ToInt()}".GetBytes().ToUrlBase64() + "." + token.Substring("."); var rs3 = prv2.TryDecode(token, out var user3, out var time3); Assert.False(rs3); Assert.NotEqual(user, user3); Assert.Equal(time.Trim(), time3.Trim());總結(jié)
在JWT大行其道的今天,數(shù)字簽名令牌仍然具有很多使用場景。JWT令牌實在太長了,HS256有密鑰安全問題,RS256/ES256在實現(xiàn)上又有較高難度,它的數(shù)據(jù)部分對于非web場景顯得過份臃腫!
總結(jié)
以上是生活随笔為你收集整理的分布式数字签名令牌TokenProvider的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 压缩解压缩
- 下一篇: 使用 Tye 辅助开发 k8s 应用竟如