我正在生成一个公钥/私钥对,我将使用jose4j进行JWT的数字签名。它的工作正常,也可以创建和验证令牌。但是一旦我重新启动服务器,之前发布的令牌就会失效。 我觉得每次重启服务器都会创建新密钥。这就是我在构造函数中生成键的方法:
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
// Give the JWK a Key ID (kid), which is just the polite thing to do
rsaJsonWebKey.setKeyId("secretKey");
当我们尝试创建新的类实例时也会发生这种情况。它说令牌无效。
任何帮助将不胜感激。感谢..
答案 0 :(得分:4)
每次拨打RsaJwkGenerator.generateJwk(...)
都会生成一个新的公钥/私钥对。 JWT上使用私钥签名的签名只能使用相应的公钥进行验证(这是安全的一大部分)。最重要的是,需要为给定的上下文使用适当的密钥,这表明在应用程序中访问密钥的方式不同。
因此,对于需要相同密钥的某些类的不同实例,密钥的某种单例可能是合适的。
为了在应用程序重新启动后继续存在,需要以某种方式持久保存和加载密钥。使用Java的密钥库是一种可以做到这一点的方法。或者整个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();
// 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));