Facing Issue with JWT decryption?

Hello Team,

I am using Key value map policy to fetch private key and public key with respect to the password.

While decrypting we are getting an error like parse object null bad input.

java.lang.IllegalStateException: Parsed object is null. Bad input.
    at com.google.apigee.util.KeyUtil.decodePrivateKey(KeyUtil.java:73)
    at com.google.apigee.edgecallouts.VerifyBase.getPrivateKey(VerifyBase.java:53)
    at com.google.apigee.edgecallouts.VerifyBase.getPolicyConfiguration(VerifyBase.java:80)
    at com.google.apigee.edgecallouts.VerifyBase.execute(VerifyBase.java:91)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$ClassLoadWrappedExecution.execute(JavaCalloutStepDefinition.java:235)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution$1.run(JavaCalloutStepDefinition.java:302)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution$1.run(JavaCalloutStepDefinition.java:300)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution.execute(JavaCalloutStepDefinition.java:300)
    at com.apigee.steps.javacallout.JavaCalloutStepDefinition$CallOutWrapper.execute(JavaCalloutStepDefinition.java:169)
    at com.apigee.messaging.runtime.steps.StepExecution.execute(StepExecution.java:157)
    at com.apigee.flow.execution.AbstractAsyncExecutionStrategy$AsyncExecutionTask.call(AbstractAsyncExecutionStrategy.java:82)
    at com.apigee.flow.execution.AbstractAsyncExecutionStrategy$AsyncExecutionTask.call(AbstractAsyncExecutionStrategy.java:48)
    at com.apigee.threadpool.CallableWrapperForMDCPreservation.call(CallableWrapperForMDCPreservation.java:26)
    at com.apigee.threadpool.ThreadPoolManager$QueueAwareCallableTask.call(ThreadPoolManager.java:546)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

ejwt_exception java.lang.IllegalStateException: Parsed object is null. Bad input.

ejwt_error Parsed object is null. Bad input.

could anyone please help on this.

Thank you.

Solved Solved
0 7 861
2 ACCEPTED SOLUTIONS

It looks to me that the policy is not successfully de-serializing the private RSA Key.  

Have you succeeded in getting the policy to work using the supplied example? which uses AssignMessage to assign values into private.private_key and so on?  Did that work for you? 

If so, can you try embedding YOUR key into the AssignMessage policy, to see if you can get the same thing to work with your key? 

In my experience, the #1 reason people have trouble with this callout is... configuring their  RSA keys correctly.  And the #1 reason they don't get the keys correctly configured, is that the keys are not properly formatted. Your private key, whether embedded in an AssignMessage policy or in a KVM, should look like this: 

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXk9k01JrhGQf1
8xaz45QmARgwI/g25gO8hP9iBABk3iNBY96+Kr65ReY8Ivof6Y2yha0ZPEwEfehQ
...
hHYu+QiRZnABbpD9C1+Akh4dG97Woyfd5igBsT1Ovs9PDCN0rO4I2nJHrNLJSPte
OtpRWoF2/LERvp6RNeXthgs=
-----END PRIVATE KEY-----

 

I suggest that you embed your thing that looks very much like that, directly into an AssignMessage policy.  Then configure the JavaCallout to read the private key from that variable. (Also set the private key password that way). Once you have that working, try to convert, to using the encrypted KVM. 

The next thing you should examine is ... your private key password. I see that you are retrieving the private key from KVM into a variable "private.my_private_key".  If the KVM is an encrypted KVM, then the variable name MUST be prefixed with "private." as you are doing for the privatekey.  But notice, you do not use the "private." prefix for the private key password. I don't know for sure, but I suspect the variable that you THINK is holding the private key password may be null (empty).  I think you should change the policy to be something like this: 

<KeyValueMapOperations name='KVM-Key' mapIdentifier='secrets'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>180</ExpiryTimeInSecs>
  <Get assignTo='private.my_private_key'>
    <Key>
      <Parameter>RSA_privatekey</Parameter>
    </Key>
  </Get>
  <Get assignTo='private.my_private_key_password'>
    <Key>
      <Parameter>RSA_privatekey_password</Parameter>
    </Key>
  </Get>
</KeyValueMapOperations>

 

To troubleshoot that, use an additional AssignMessage policy, to assign the variable that is private to a non-private variable. 

<AssignMessage name-'AM-Diagnostics'>
  <AssignVariable> 
    <Name>check1</Name>
    <Ref>private.my_private_key</Ref>
  </AssignVariable>
  <AssignVariable> 
    <Name>check2</Name>
    <!-- this should be the name of the variable you extracted from KVM -->
    <Ref>private.my_private_key_password</Ref>
  </AssignVariable>
</AssignMessage>

Then view the transaction in Apigee trace.  You'll see the value of variables you retrieved from KVM. If they do not hold what you think they should hold, check your KVM parameters and values! 

Last thing:

  • The encrypted JWT callout has been updated.  Get the one from April 2021.  I don't believe there were specific changes to the deserialization of keys, but it's best to use the latest stable version.

View solution in original post

Hi

Your responses are very terse.  Remember, I cannot see what you are doing, and I don't know exaclty what you are trying.  You said "we are getting password value but not private key value".  I suppose this means you are using the AssignMessage technique I suggested and you have confirmed that the variable that you expect to hold the password is correct,and the variable that you expect to hold the private key is not correct. 

 

In that case I would suggest you backtrack - and check your KVM settings. If you are uncertain, reload the privatekey PEM that you loaded into the KVM. Verify that the parameter you use on the KVM GET is the same parameter value (case sensitive) that you use on the KVM PUT.  

You're pretty close.

View solution in original post

7 REPLIES 7

 

Hello @sravanig231 ,

Can you please add little more details?

1. Policy details(KVM & JWT )

2.if possible sample proxy which can be used to reproduce

 

one way to isolate is to try first hard code the values to see if it works -meaning use assign assign  variable and pass variables and test.

once it works as expected please move config as always (never hard code as stated earlier) to KVM and make sure the certs are properly formatted into kvm and retest.

 

https://docs.apigee.com/api-platform/reference/policies/verify-jwt-policy

 

General Notes:

For future (any post) as well if we get better info it will be easy to quickly help in resolution.

 

 

Hello 

JWT.PNGkvm.PNG

I tried with assign message policy by hardcoded keys, in that case verify jwt is working fine.

But in case of using KVM policy, I am getting error like org.bouncycastle.openssl.PEMException: problem creating RSA private key: java.lang.IllegalArgumentException: failed to construct sequence from byte[]: DER length more than 4 bytes: 24 

Case 1:

If I am assigning kvm parameters name directly into javacallout policy then iam getting error as ejwt_exception java.lang.IllegalStateException: Parsed object is null. Bad input.

Please help on this.

Thank you.

It looks to me that the policy is not successfully de-serializing the private RSA Key.  

Have you succeeded in getting the policy to work using the supplied example? which uses AssignMessage to assign values into private.private_key and so on?  Did that work for you? 

If so, can you try embedding YOUR key into the AssignMessage policy, to see if you can get the same thing to work with your key? 

In my experience, the #1 reason people have trouble with this callout is... configuring their  RSA keys correctly.  And the #1 reason they don't get the keys correctly configured, is that the keys are not properly formatted. Your private key, whether embedded in an AssignMessage policy or in a KVM, should look like this: 

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXk9k01JrhGQf1
8xaz45QmARgwI/g25gO8hP9iBABk3iNBY96+Kr65ReY8Ivof6Y2yha0ZPEwEfehQ
...
hHYu+QiRZnABbpD9C1+Akh4dG97Woyfd5igBsT1Ovs9PDCN0rO4I2nJHrNLJSPte
OtpRWoF2/LERvp6RNeXthgs=
-----END PRIVATE KEY-----

 

I suggest that you embed your thing that looks very much like that, directly into an AssignMessage policy.  Then configure the JavaCallout to read the private key from that variable. (Also set the private key password that way). Once you have that working, try to convert, to using the encrypted KVM. 

The next thing you should examine is ... your private key password. I see that you are retrieving the private key from KVM into a variable "private.my_private_key".  If the KVM is an encrypted KVM, then the variable name MUST be prefixed with "private." as you are doing for the privatekey.  But notice, you do not use the "private." prefix for the private key password. I don't know for sure, but I suspect the variable that you THINK is holding the private key password may be null (empty).  I think you should change the policy to be something like this: 

<KeyValueMapOperations name='KVM-Key' mapIdentifier='secrets'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>180</ExpiryTimeInSecs>
  <Get assignTo='private.my_private_key'>
    <Key>
      <Parameter>RSA_privatekey</Parameter>
    </Key>
  </Get>
  <Get assignTo='private.my_private_key_password'>
    <Key>
      <Parameter>RSA_privatekey_password</Parameter>
    </Key>
  </Get>
</KeyValueMapOperations>

 

To troubleshoot that, use an additional AssignMessage policy, to assign the variable that is private to a non-private variable. 

<AssignMessage name-'AM-Diagnostics'>
  <AssignVariable> 
    <Name>check1</Name>
    <Ref>private.my_private_key</Ref>
  </AssignVariable>
  <AssignVariable> 
    <Name>check2</Name>
    <!-- this should be the name of the variable you extracted from KVM -->
    <Ref>private.my_private_key_password</Ref>
  </AssignVariable>
</AssignMessage>

Then view the transaction in Apigee trace.  You'll see the value of variables you retrieved from KVM. If they do not hold what you think they should hold, check your KVM parameters and values! 

Last thing:

  • The encrypted JWT callout has been updated.  Get the one from April 2021.  I don't believe there were specific changes to the deserialization of keys, but it's best to use the latest stable version.

Hello Team,

We are getting password value but we are not getting private key value in trace.

Please help on this.

Thank you,

@sravanig231 

This is a separate question but in general Private variable values doesn't showup in trace. You  need to use assign message to see the values during debugging.

Hi

Your responses are very terse.  Remember, I cannot see what you are doing, and I don't know exaclty what you are trying.  You said "we are getting password value but not private key value".  I suppose this means you are using the AssignMessage technique I suggested and you have confirmed that the variable that you expect to hold the password is correct,and the variable that you expect to hold the private key is not correct. 

 

In that case I would suggest you backtrack - and check your KVM settings. If you are uncertain, reload the privatekey PEM that you loaded into the KVM. Verify that the parameter you use on the KVM GET is the same parameter value (case sensitive) that you use on the KVM PUT.  

You're pretty close.

I agree with @API-Evangelist. More details. 

 

I see two options: 

 

1. corrupted private key

2. payload of JWT is null