重新启动服务器后,JWT将无效 [英] JWT becomes invalid after restarting the server

查看:2300
本文介绍了重新启动服务器后,JWT将无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在生成一个公钥/私钥对,我将用于jose4j的JWT的数字签名。它的工作也很好地创建和验证了令牌。但是一旦我重新启动服务器,那么以前发出的令牌就变得无效了。
我觉得每次重新启动服务器,它创建新的密钥。这是我如何在构造函数中生成密钥:

  rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); 
//给JWK一个密钥ID(小孩),这只是有礼貌的事情要做
rsaJsonWebKey.setKeyId(secretKey);

当我们尝试创建新的类实例时,也会发生这种情况。它表示令牌无效。



任何帮助将不胜感激。谢谢..

解决方案

每次调用 RsaJwkGenerator.generateJwk(...)生成一个新的公钥/私钥对。使用私钥签名的JWT上的签名只能使用相应的公钥(这是安全性的一大部分)进行验证。底线是适当的密钥需要用于给定的上下文,并且提示了访问应用程序中的密钥的不同方法。



因此,对于需要相同密钥的某些类的不同实例,某些密钥的单例可能是合适的。



要重新启动应用程序,密钥需要持续保存并以某种方式加载。使用java的Keystore是一种可以做到这一点的方法。或者整个JWK的JSON可以以 rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE)作为字符串访问,并保存在某个地方。你确实要小心使用私钥,但这样可以将其保存在某个安全的地方,或者也可以使用JWE加密整个事物 - 一些使用基于密码的加密的一些代码如下所示:

  String jwkjson = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE); 
JsonWebEncryption encryptingJwe = new JsonWebEncryption();
encryptingJwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.PBES2_HS256_A128KW);
encryptingJwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
encryptingJwe.setKey(new PbkdfKey(some decent passphrase / password here));
encryptingJwe.setPayload(jwkjson);
String jweEncryptedJwk = encryptingJwe.getCompactSerialization();

//将jweEncryptedJwk保存在某处并将其加载到应用程序启动

JsonWebEncryption decryptingJwe = new JsonWebEncryption();
decryptingJwe.setCompactSerialization(jweEncryptedJwk);
encryptingJwe.setKey(new PbkdfKey(some decent passphrase / password here));
String payload = encryptingJwe.getPayload();
PublicJsonWebKey publicJsonWebKey = PublicJsonWebKey.Factory.newPublicJwk(payload);
//与任何需要验证签名的人共享公共部分
System.out.println(publicJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY));


I am generating a public/private key pair which i will use for digital signature of a JWT with jose4j. Its working fine creating and validating the token as well. But once i restart the server, then the previously issued tokens become invalid. I feel that everytime i restart the server it creates the new key. This is how i generate key inside the constructor:

    rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
    // Give the JWK a Key ID (kid), which is just the polite thing to do
    rsaJsonWebKey.setKeyId("secretKey");

It also happens when we try to create new instance of class. It says the token is invalid.

Any help would be appreciated. Thanks..

解决方案

Each call to RsaJwkGenerator.generateJwk(...) generates a new public/private key pair. A signature on a JWT that's signed with a private key can only be verified with the corresponding public key (that's a big piece of the security). Bottom line is that the appropriate key needs to be used for the given context and that suggests a different way of accessing the key in your application.

So for different instances of some class needing the same key, some kind of singleton for the key might be appropriate.

To survive application restarts, the key needs to be persisted and loaded somehow. Using java's Keystore is one way you could do that. Or the whole JWK's JSON can be accessed as a String with rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE) and saved somewhere. You do want to be careful with the private key though so save it somewhere secure and/or maybe you could encrypt the whole thing with a JWE - a little code for some of that using password based encryption is shown here:

    String jwkjson = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
    JsonWebEncryption encryptingJwe = new JsonWebEncryption();
    encryptingJwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.PBES2_HS256_A128KW);
    encryptingJwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
    encryptingJwe.setKey(new PbkdfKey("some decent passphrase/password here"));
    encryptingJwe.setPayload(jwkjson);
    String jweEncryptedJwk = encryptingJwe.getCompactSerialization();

    // save  jweEncryptedJwk somewhere  and load it on application start 

    JsonWebEncryption decryptingJwe = new JsonWebEncryption();
    decryptingJwe.setCompactSerialization(jweEncryptedJwk);
    encryptingJwe.setKey(new PbkdfKey("some decent passphrase/password here"));
    String payload = encryptingJwe.getPayload();
    PublicJsonWebKey publicJsonWebKey = PublicJsonWebKey.Factory.newPublicJwk(payload);
    // share the public part with whomever/whatever needs to verify the signatures 
    System.out.println(publicJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY));

这篇关于重新启动服务器后,JWT将无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆