Open barramandi opened 3 years ago
Do we have any updated code for this issue.
@zoltantarcsay Any suggestion on this issue would be helpful
@jasarmcj could you send the full stack trace?
Hi @zoltantarcsay here is the complete stack trace
org.forgerock.json.jose.exceptions.JweEncryptionException: java.security.InvalidKeyException at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.encrypt(AESCBCHMACSHA2ContentEncryptionHandler.java:81) at org.forgerock.json.jose.jwe.handlers.encryption.DirectEncryptionHandler.encryptPlaintext(DirectEncryptionHandler.java:58) at org.forgerock.json.jose.jwe.EncryptedJwt.build(EncryptedJwt.java:162) at com.forgerock.backstage.ssoextensions.auth.oath.OathHelper.encrypt(OathHelper.java:115) at com.forgerock.backstage.ssoextensions.auth.oath.OathHelper.encryptOathDeviceSettings(OathHelper.java:85) at com.forgerock.backstage.ssoextensions.auth.oath.registration.OathRegistrationNode.createDeviceProfileAndFinishWithCallbacks(OathRegistrationNode.java:97) at com.forgerock.backstage.ssoextensions.auth.oath.registration.OathRegistrationNode.process(OathRegistrationNode.java:86) at org.forgerock.openam.auth.trees.engine.AuthTreeExecutor.process(AuthTreeExecutor.java:107) at org.forgerock.openam.auth.trees.engine.AuthTreeExecutor.process(AuthTreeExecutor.java:154) at org.forgerock.openam.auth.trees.engine.AuthTreeExecutor.process(AuthTreeExecutor.java:154) at org.forgerock.openam.auth.trees.engine.AuthTreeExecutor.process(AuthTreeExecutor.java:154) at org.forgerock.openam.core.rest.authn.trees.AuthTrees.processTree(AuthTrees.java:423) at org.forgerock.openam.core.rest.authn.trees.AuthTrees.evaluateTreeAndProcessResult(AuthTrees.java:263) at org.forgerock.openam.core.rest.authn.trees.AuthTrees.invokeTree(AuthTrees.java:255) at org.forgerock.openam.core.rest.authn.RestAuthenticationHandler.authenticate(RestAuthenticationHandler.java:230) at org.forgerock.openam.core.rest.authn.http.AuthenticationServiceV1.authenticate(AuthenticationServiceV1.java:162) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.forgerock.openam.http.annotations.AnnotatedMethod.invoke(AnnotatedMethod.java:76) at org.forgerock.openam.http.annotations.Endpoints$1.handle(Endpoints.java:64) at org.forgerock.http.routing.Router.handle(Router.java:100) at org.forgerock.openam.audit.AbstractHttpAccessAuditFilter.filter(AbstractHttpAccessAuditFilter.java:59) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.routing.Router.handle(Router.java:100) at org.forgerock.openam.rest.RealmContextFilter.filter(RealmContextFilter.java:87) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.routing.Router.handle(Router.java:100) at org.forgerock.http.routing.Router.handle(Router.java:100) at org.forgerock.openam.rest.CsrfFilter.filter(CsrfFilter.java:95) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.routing.ResourceApiVersionRoutingFilter.filter(ResourceApiVersionRoutingFilter.java:59) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.caf.authentication.framework.AuthenticationFramework.grantAccess(AuthenticationFramework.java:188) at org.forgerock.caf.authentication.framework.AuthenticationFramework.lambda$onValidateRequestSuccess$1(AuthenticationFramework.java:181) at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:260) at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:249) at org.forgerock.caf.authentication.framework.AuthenticationFramework.validateRequest(AuthenticationFramework.java:144) at org.forgerock.caf.authentication.framework.AuthenticationFramework.processMessage(AuthenticationFramework.java:134) at org.forgerock.caf.authentication.framework.AuthenticationFilter.filter(AuthenticationFilter.java:84) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.openam.http.GuiceHandler.handle(GuiceHandler.java:51) at org.forgerock.openam.http.HttpRoute$6.handle(HttpRoute.java:206) at org.forgerock.http.routing.Router.handle(Router.java:100) at org.forgerock.openam.dpro.session.ProofOfPossessionTokenFilter.filter(ProofOfPossessionTokenFilter.java:87) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.swagger.OpenApiRequestFilter.filter(OpenApiRequestFilter.java:63) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.openam.http.ApiDescriptorFilter.filter(ApiDescriptorFilter.java:139) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.openam.http.OpenAMHttpApplication$1.filter(OpenAMHttpApplication.java:74) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.filter.TransactionIdInboundFilter.filter(TransactionIdInboundFilter.java:86) at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53) at org.forgerock.http.servlet.HttpFrameworkServlet.service(HttpFrameworkServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.services.datastore.DataStoreConsistencyFilter.lambda$doFilter$0(DataStoreConsistencyFilter.java:46) at org.forgerock.openam.service.datastore.ReentrantVolatileActionConsistencyController.safeExecute(ReentrantVolatileActionConsistencyController.java:37) at org.forgerock.openam.services.datastore.DataStoreConsistencyFilter.doFilter(DataStoreConsistencyFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.rest.ProtocolVersionFilter.doFilter(ProtocolVersionFilter.java:62) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.headers.DisableSameSiteCookiesFilter.doFilter(DisableSameSiteCookiesFilter.java:105) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.validation.ResponseValidationFilter.doFilter(ResponseValidationFilter.java:59) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.headers.SetHeadersFilter.doFilter(SetHeadersFilter.java:80) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.headers.SetHeadersFilter.doFilter(SetHeadersFilter.java:80) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:115) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.forgerock.openam.audit.context.AuditContextFilter.doFilter(AuditContextFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: java.security.InvalidKeyException at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.validateKey(AESCBCHMACSHA2ContentEncryptionHandler.java:176) at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.encrypt(AESCBCHMACSHA2ContentEncryptionHandler.java:59) ... 104 more
The code wants to use EncryptionMethod.A128CBC_HS256, so make sure that the key being used supports that. The key being used is the one referenced as "am.services.oauth2.stateless.token.encryption". You can look up the alias of this key in the keystore on the secret store config page in AM (e.g. #configure/secretStores/KeyStoreSecretStore/edit/default-keystore, or if you have a different keystore defined for your realm, then there). If this key doesn't exist or is not the right length or type, you should generate a new key and add it to your keystore.
here's what EncryptionMethod.A128CBC_HS256 looks like:
/**
* AES encryption in CBC mode with PKCS5 Padding and a 128 bit length, AES encryption for CEK, HMA
* hash algorithm for authentication tag.
*/
A128CBC_HS256("AES_128_CBC_HMAC_SHA_256", "AES/CBC/PKCS5Padding", "HMACSHA256", "AES", 16, 256),
The am.services.oauth2.stateless.token.encryption provides the alias name of key to be used for encryption. The default value is directenctest in the keystore provided with AM installation (I am using AM 6.5.3)
The encrypt method uses this key and checks for predefined allowed algorithms.
When this alias is read as key its algorithm is "RAW" and not AES which FR framework expects in allowed algorithms.
Hence it is required to generate new key with algo AES.
keytool gensekey with AES algo should have helped, but key generated with keytool when loaded with java code, shows algorithm RAW.. So here is what needs to be done:
Here is the program to save the AES key in keystore: import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.security.Key; import java.security.KeyStore; import java.security.cert.Certificate;
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey;
import org.forgerock.json.jose.jwe.EncryptionMethod;
public class StoreAESKey {
/**
* This class creates a Symmetric key with AES algo with size 256 bits and stores it in a keystore.
*
* The stored key can be imported to another keystore using keytool command.
* Sample keytool command:
*
* keytool -importkeystore -srckeystore D:\\temp.jceks -
* srcstorepass pass -srckeypass pass -srcalias directenctest
* -destalias directenctest -destkeystore D:\\keystore.jceks
* -srcstoretype JCEKS -deststoretype JCEKS -deststorepass pass
* -destkeypass pass
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String keystorePass = "pass";
String alias = "directenctest";
String keyPass= "pass";
String keystoreLocation = "D:\\temp.jceks";
FileOutputStream fos = new FileOutputStream(keystoreLocation);
KeyStore keystore = KeyStore.getInstance("JCEKS");
keystore.load(null, null);
KeyGenerator instance = KeyGenerator.getInstance("AES");
instance.init(256);
SecretKey generateKey = instance.generateKey();
Certificate[] cert = {};
keystore.setKeyEntry(alias, generateKey, keyPass.toCharArray(), cert);
keystore.store(fos, keystorePass.toCharArray());
fos.close();
// read the key and check its algorithm. InputStream keystoreStream = new FileInputStream(keystoreLocation);
keystore = KeyStore.getInstance("JCEKS");
keystore.load(keystoreStream, keystorePass.toCharArray());
keystoreStream.close();
if (!keystore.containsAlias(alias)) {
throw new RuntimeException("Alias for key not found");
}
Key key = keystore.getKey(alias, keyPass.toCharArray());
//check the key algorithm
System.out.println("key algo=" + key.getAlgorithm() + " key format=" + key.getFormat() + " encoded key=" + key.getEncoded() );
}
}
Here is the program to inspect the key from keystore:
import java.io.FileInputStream; import java.io.InputStream; import java.security.Key; import java.security.KeyStore;
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec;
import org.forgerock.json.jose.jwe.EncryptionMethod;
public class GetAESKey {
public static void main(String[] args) throws Exception {
String keystorePass = "pass";
String alias = "directenctest";
String keyPass= "pass";
String keystoreLocation = "D:\\\\keystore.jceks";
InputStream keystoreStream = new FileInputStream(keystoreLocation);
KeyStore keystore = KeyStore.getInstance("JCEKS");
keystore.load(keystoreStream, keystorePass.toCharArray());
if (!keystore.containsAlias(alias)) {
throw new RuntimeException("Alias for key not found");
}
Key key = keystore.getKey(alias, keyPass.toCharArray());
System.out.println("key algo=" + key.getAlgorithm() + " key format=" + key.getFormat() + " encoded key=" + key.getEncoded() );
System.out.println(EncryptionMethod.A128CBC_HS256.getEncryptionAlgorithm());
System.out.println(EncryptionMethod.A128CBC_HS256.getMacAlgorithm());
System.out.println(EncryptionMethod.A128CBC_HS256.getKeySize());
}
}
When user have no device registered and entered the regisration node, it seems the key generation failed.
Caused by: org.forgerock.json.jose.exceptions.JweEncryptionException: java.security.InvalidKeyException at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.encrypt(AESCBCHMACSHA2ContentEncryptionHandler.java:85) at org.forgerock.json.jose.jwe.handlers.encryption.DirectEncryptionHandler.encryptPlaintext(DirectEncryptionHandler.java:58) at org.forgerock.json.jose.jwe.EncryptedJwt.build(EncryptedJwt.java:162) at com.forgerock.backstage.ssoextensions.auth.oath.OathHelper.encrypt(Unknown Source) at com.forgerock.backstage.ssoextensions.auth.oath.OathHelper.encryptOathDeviceSettings(Unknown Source) at com.forgerock.backstage.ssoextensions.auth.oath.registration.OathRegistrationNode.createDeviceProfileAndFinishWithCallbacks(Unknown Source) at com.forgerock.backstage.ssoextensions.auth.oath.registration.OathRegistrationNode.process(Unknown Source) at org.forgerock.openam.auth.trees.engine.AuthTreeExecutor.process(AuthTreeExecutor.java:143) ... 122 common frames omitted Caused by: java.security.InvalidKeyException: null at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.validateKey(AESCBCHMACSHA2ContentEncryptionHandler.java:180) at org.forgerock.json.jose.jwe.handlers.encryption.AESCBCHMACSHA2ContentEncryptionHandler.encrypt(AESCBCHMACSHA2ContentEncryptionHandler.java:63) ... 129 common frames omitted