jwt令牌_JWT令牌的秘密轮换
jwt令牌
當(dāng)您使用JSON Web令牌 ( JWT )或需要對有效載荷信息進(jìn)行簽名或加密的任何其他令牌技術(shù)時(shí),設(shè)置令牌的到期日期很重要,因此,如果令牌到期,則可以假定這可能被視為安全漏洞,您拒絕使用此令牌進(jìn)行任何通信,或者您決定通過使用新的到期日期更新令牌來啟用該令牌。
但是使用某種秘密輪換算法也很重要,因此用于簽名或加密令牌的秘密會定期更新,因此,如果該秘密受到威脅,則此密鑰泄漏的令牌會更少。 同樣,您也可以減少機(jī)密被破解的可能性。
有幾種策略可以實(shí)現(xiàn)這一目的,但是在這篇文章中,我將解釋我如何在幾年前開發(fā)的一個(gè)項(xiàng)目中實(shí)現(xiàn)秘密輪換
具有HMAC算法的JWT令牌。
我將展示如何在Java中創(chuàng)建JWT令牌。
try {Algorithm algorithm = Algorithm.HMAC256("secret");String token = JWT.create().withIssuer("auth0").sign(algorithm);} catch (UnsupportedEncodingException exception){//UTF-8 encoding not supported } catch (JWTCreationException exception){//Invalid Signing configuration / Couldn't convert Claims. }請注意,這里您需要做的是創(chuàng)建一個(gè)算法對象設(shè)置HMAC算法,并設(shè)置用于簽署和驗(yàn)證實(shí)例的密鑰。
因此,我們需要每X分鐘旋轉(zhuǎn)一次該算法實(shí)例,因此破解密碼的機(jī)率以及破解的密碼仍然有效的機(jī)率變得非常低。
那么如何旋轉(zhuǎn)秘密呢? 好吧,通過一個(gè)非常簡單的算法,每個(gè)人(即使您不是加密專家)也可以理解。 只是浪費(fèi)時(shí)間。
因此,要生成秘密,您需要一個(gè)字符串,在上一個(gè)示例中,它是秘密字符串,當(dāng)然,它并不是那么安全,所以我們的想法是通過根(我們稱之為“大爆炸”部分)來組成這個(gè)秘密字符串+兼職。 總之,秘密是<bigbang> + <timeInMilliseconds>
Bing bang部分沒有任何奧秘,它只是一個(gè)靜態(tài)部分,例如my_super_secret 。
有趣的部分是時(shí)間部分。 假設(shè)您想每秒更新一次秘密。 您只需要這樣做:
long t = System.currentTimeMillis();System.out.println(t); System.out.println((t/1000)*1000);TimeUnit.MILLISECONDS.sleep(50);t = System.currentTimeMillis(); System.out.println((t/1000)*1000);我只是將0設(shè)置為毫秒部分,所以如果運(yùn)行此命令,我將得到類似以下內(nèi)容:
1515091335543 1515091335500 1515091335500請注意,盡管在第二和第三次打印之間已經(jīng)過了50毫秒,但時(shí)間部分是完全相同的。 在同一秒內(nèi)將是相同的。
當(dāng)然,這是一個(gè)極端的示例,其中秘密每秒鐘更改一次,但其想法是您刪除要忽略的部分時(shí)間,并用0填充。 因此,首先,您要除以時(shí)間,然后再乘以相同的數(shù)字。
例如,假設(shè)您想每10分鐘旋轉(zhuǎn)一次秘密,您只需要除以600000就可以了。
這種方法有兩個(gè)問題可以解決,盡管其中一個(gè)并不是很大的問題。
第一個(gè)是因?yàn)槿绻朊糠昼姼囊淮螜C(jī)密,則您要縮短時(shí)間,例如,第一次計(jì)算是在一分鐘的中間進(jìn)行的,因此,對于這種初始情況,輪換將在30秒后發(fā)生,并且不是1分鐘。 這不是一個(gè)大問題,在我們的項(xiàng)目中,我們沒有做任何修復(fù)。
第二個(gè)是在秘密輪換之前簽名的令牌的情況,它們?nèi)匀挥行?#xff0c;您還需要能夠驗(yàn)證它們,而不是使用新的秘密,而要使用之前的一個(gè)。
為了解決這個(gè)問題,我們要做的是創(chuàng)建一個(gè)有效窗口,其中還保留了先前的有效機(jī)密。 因此,當(dāng)系統(tǒng)收到令牌時(shí),將使用當(dāng)前機(jī)密驗(yàn)證該令牌,如果該令牌通過,則我們可以進(jìn)行其他任何檢查并使用它,如果未通過,則令牌將由先前的機(jī)密驗(yàn)證。 如果通過,則重新創(chuàng)建令牌并使用新的秘密對其進(jìn)行簽名;如果未通過,則顯然此令牌無效,必須拒絕。
要為JWT創(chuàng)建算法對象,您只需執(zhí)行以下操作:
long currentTime = System.currentTimeMillis();try {return Algorithm.HMAC256("my_big_bang" + (currentTime/60000)*60000); } catch (UnsupportedEncodingException e) {throw new IllegalArgumentException(e); }我真正喜歡這種解決方案的地方是:
- 它很干凈,系統(tǒng)上不需要額外的元素。
- 不需要異步運(yùn)行的觸發(fā)線程來更新密碼。
- 它確實(shí)性能很高,您無需訪問外部系統(tǒng)。
- 測試服務(wù)真的很容易。
- 驗(yàn)證過程負(fù)責(zé)旋轉(zhuǎn)機(jī)密。
- 擴(kuò)展確實(shí)很容易,實(shí)際上,您無需執(zhí)行任何操作,可以添加同一服務(wù)的越來越多的實(shí)例,并且所有實(shí)例都將同時(shí)旋轉(zhuǎn)秘密,并且所有實(shí)例都將使用同樣的秘密,因此輪換過程實(shí)際上是無狀態(tài)的,您可以按比例放大或縮小實(shí)例,所有實(shí)例將繼續(xù)能夠驗(yàn)證其他實(shí)例簽名的令牌。
但是當(dāng)然有一些缺點(diǎn):
- 您仍然需要以安全的方式向每個(gè)服務(wù)共享機(jī)密的一部分(大爆炸部分)。 也許使用Kubernetes機(jī)密,Hashicorp的Vault,或者如果您不使用微服務(wù),則可以將文件復(fù)制到具體位置,并在服務(wù)啟動和運(yùn)行時(shí)閱讀大爆炸部分,然后將其刪除。
- 如果您的物理服務(wù)器位于不同的時(shí)區(qū),則使用此方法可能會遇到更多問題。 另外,您需要使服務(wù)器或多或少同步。 由于您要存儲以前的令牌和當(dāng)前令牌,因此不必在同一秒內(nèi)同步它們,并且?guī)酌腌姷难舆t仍然可能沒有問題。
因此,我們已經(jīng)看到了一種非常簡單的秘密輪換方式,可以使令牌更安全。 當(dāng)然,還有其他方法可以做到這一點(diǎn)。 在這篇文章中,我只是解釋了我是如何在三年前開發(fā)的整體應(yīng)用程序中做到這一點(diǎn)的,它確實(shí)運(yùn)行良好。
我們不斷學(xué)習(xí),
亞歷克斯
翻譯自: https://www.javacodegeeks.com/2018/01/secret-rotation-jwt-tokens.html
jwt令牌
總結(jié)
以上是生活随笔為你收集整理的jwt令牌_JWT令牌的秘密轮换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑主板没供电是什么原因(主板不供电是什
- 下一篇: jasperreports_Jasper