JWT становится недействительным после перезапуска сервера
Я генерирую пару открытый / закрытый ключ, который я буду использовать для цифровой подписи JWT с jose4j. Хорошо работает создание и проверка токена. Но после перезапуска сервера ранее выданные токены становятся недействительными. Я чувствую, что каждый раз, когда я перезагружаю сервер, он создает новый ключ. Вот как я генерирую ключ внутри конструктора:
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
// Give the JWK a Key ID (kid), which is just the polite thing to do
rsaJsonWebKey.setKeyId("secretKey");
Это также происходит, когда мы пытаемся создать новый экземпляр класса. Он говорит, что токен недействителен.
Любая помощь будет оценена. Спасибо..
1 ответ
Каждый звонок RsaJwkGenerator.generateJwk(...)
генерирует новую пару открытый / закрытый ключ. Подпись на JWT, подписанном с помощью закрытого ключа, может быть проверена только с помощью соответствующего открытого ключа (это большая часть защиты). Суть в том, что соответствующий ключ должен использоваться для данного контекста, и это предлагает другой способ доступа к ключу в вашем приложении.
Таким образом, для разных экземпляров некоторого класса, нуждающихся в одном и том же ключе, может подойти какой-то одиночный ключ для ключа.
Чтобы выжить, приложение перезапускается, ключ необходимо как-то сохранить и как-то загрузить. Использование хранилища ключей Java - это единственный способ сделать это. Или весь JSON JWK может быть доступен как строка с 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));