I was using inbuild policy to generate and encrypt token. Selected A256KW for key encryption. However, when I am giving 256 bit key, I am getting an error regarding length of the key. It is working for me once I make the key 128 bit.
Key samples:
E9DB7E89123F52A9F2DB04EF04C7FE88 (working).
E9DB7E89123F52A9F2DB04EF04C7FE8874C737410EFCFE2277574F35ABD7A894 (not working).
Solved! Go to Solution.
Thanks for that information. For A256KW, the length of the Key Encryption Key must be 256 bits.
Your configuration shows the SecretKey element like this:
<SecretKey>
<Value ref='private.key'/>
</SecretKey>
You did not specify an encoding attribute on the Value element. By default, Apigee will decode the string you pass as the secret key, via UTF-8. That means for each character in the string, Apigee will decode 8 bits. If you pass a string of length 64, Apigee will return a key that is 64 * 8 = 512 bits long. That's too long! Which is why you see the error you see.
Actually the error message indicates "Insufficient Key Length" which suggests the key you provided is too short. But that's not correct. Really the message should read "Inappropriate Key Length", meaning that the key is not the right length for the algorithm you specified. Sorry about the confusion here! The exception is expected, the message could be better.
From the format of the key value, I am guessing that your intent is for Apigee to decode that string from a HEX (or base16) encoding. 64 characters of Hex would give you 4 bits per character, which is 64 *4 = 256 bits total, and that is the correct length of key for A256KW. To do that, you need this configuration:
<SecretKey encoding='hex'>
<Value ref='private.key' />
</SecretKey>
Hex decoding will work only for keys that use only HEX digits in the key string: 0-9A-F.
When I try this without the encoding attribute, I see the behavior you reported. When I try it with the encoding attribute specifying "hex", the policy succeeds in generating the encrypted JWT.
Looking now at the documentation for the policy, I can see that the encoding attribute is not documented! I'll get that fixed.
In lieu of official documentation: you can use hex
, base16
, base64
, base64url
or utf-8
for the value of the encoding attribute for the SecretKey/Value. base16 is a synonym for hex. The default is to decode via UTF-8.
I'm SORRY! I gave the wrong configuration above. The encoding
attribute needs to be on the SecretKey element. You should use THIS:
<SecretKey encoding='hex'>
<Value ref='private.key' />
</SecretKey>
I was using inbuild policy to generate and encrypt token.
Can you show the policy configuration you are using? And the specific error?
1. This is the error I received. Getting the same while debugging.
Try Encryption Key Generator online & use it. I tested it and works fine normally.
The Key Encryption Key length must be 256 bits (32 bytes)
example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="AM-TestKey">
<Name>private.key2</Name>
<Value>RfUjXnZr4u7x!A%D*G-KaPdSgVkYp3s5</Value>
</AssignVariable>
</AssignMessage>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GenerateJWT async="false" continueOnError="false" enabled="true" name="Generate-JWT-UsingA256KW-A256GCM">
<DisplayName>Generate JWT-UsingA256KW-A256GCM</DisplayName>
<Algorithms>
<Key>A256KW</Key>
<Content>A256GCM</Content>
</Algorithms>
<SecretKey>
<Value ref="private.key2"/>
</SecretKey>
<Subject>subject-subject</Subject>
<Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
<Audience>audience1,audience2</Audience>
<ExpiresIn>8h</ExpiresIn>
<AdditionalClaims>
<Claim name="additional-claim-name" type="string">additional-claim-value-goes-here</Claim>
</AdditionalClaims>
<OutputVariable>jwt-variable</OutputVariable>
</GenerateJWT>
Ref:
https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx
https://datatracker.ietf.org/doc/html/rfc7518#section-5.1
https://datatracker.ietf.org/doc/html/rfc7518#section-4.1
However
@dchiesa1 Using 64 char hex it is failing with encoding specified in the policy.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="AM-TestKey-Base64Encoded">
<AssignVariable>
<Name>private.key2</Name>
<Value>bcdcbff90b822814c1266307c5c8bb4d2c3637aa5e2d3fd9d6b844b0d1f3ddef</Value>
<!--<Value>jXnZr4u7x!A%D*G-KaPdSgVkYp3s5v8y</Value>-->
</AssignVariable>
</AssignMessage>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GenerateJWT async="false" continueOnError="false" enabled="true" name="Generate-JWT-UsingA256KW-A256GCM">
<DisplayName>Generate JWT-UsingA256KW-A256GCM</DisplayName>
<Algorithms>
<Key>A256KW</Key>
<Content>A256GCM</Content>
</Algorithms>
<SecretKey>
<Value ref="private.key2" encoding="hex"/>
</SecretKey>
<Subject>subject-subject</Subject>
<Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
<Audience>audience1,audience2</Audience>
<ExpiresIn>8h</ExpiresIn>
<AdditionalClaims>
<Claim name="additional-claim-name" type="string">additional-claim-value-goes-here</Claim>
</AdditionalClaims>
<OutputVariable>jwt-variable</OutputVariable>
</GenerateJWT>
Fails with
The Key Encryption Key length must be 128 bits (16 bytes), 192 bits (24 bytes) or 256 bits (32 bytes)
Using 64 char hex it is failing with encoding specified in the policy.
Yes, that is expected. See my answer below. It's a matter of encoding / decoding. If you have 64 characters and decode it as UTF-8, you will get 64*8 = 512 bits. That's too much. With that key string, I suspect you want to use base16 or hex decoding. This is all explained in my other answer (previously posted!)
Thanks for that information. For A256KW, the length of the Key Encryption Key must be 256 bits.
Your configuration shows the SecretKey element like this:
<SecretKey>
<Value ref='private.key'/>
</SecretKey>
You did not specify an encoding attribute on the Value element. By default, Apigee will decode the string you pass as the secret key, via UTF-8. That means for each character in the string, Apigee will decode 8 bits. If you pass a string of length 64, Apigee will return a key that is 64 * 8 = 512 bits long. That's too long! Which is why you see the error you see.
Actually the error message indicates "Insufficient Key Length" which suggests the key you provided is too short. But that's not correct. Really the message should read "Inappropriate Key Length", meaning that the key is not the right length for the algorithm you specified. Sorry about the confusion here! The exception is expected, the message could be better.
From the format of the key value, I am guessing that your intent is for Apigee to decode that string from a HEX (or base16) encoding. 64 characters of Hex would give you 4 bits per character, which is 64 *4 = 256 bits total, and that is the correct length of key for A256KW. To do that, you need this configuration:
<SecretKey encoding='hex'>
<Value ref='private.key' />
</SecretKey>
Hex decoding will work only for keys that use only HEX digits in the key string: 0-9A-F.
When I try this without the encoding attribute, I see the behavior you reported. When I try it with the encoding attribute specifying "hex", the policy succeeds in generating the encrypted JWT.
Looking now at the documentation for the policy, I can see that the encoding attribute is not documented! I'll get that fixed.
In lieu of official documentation: you can use hex
, base16
, base64
, base64url
or utf-8
for the value of the encoding attribute for the SecretKey/Value. base16 is a synonym for hex. The default is to decode via UTF-8.
Thanks you so much @dchiesa1 . This makes sense. I was totally confused seeing the error message. @API-Evangelist Thanks for your input.
Hello @dchiesa1
Getting the same key length error even when using the encoding.
this is my code :
1. Assign Key
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="Set-AES-Key">
<DisplayName>Set AES Key</DisplayName>
<Properties/>
<AssignVariable>
<Name>private.key</Name>
<Value>E9DB7E89123F52A9F2DB04EF04C7FE8874C737410EFCFE2277574F35ABD7A894</Value>
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
2. Generate token
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GenerateJWT continueOnError="false" enabled="true" name="Generate-JWT-1">
<DisplayName>Generate JWT-1</DisplayName>
<Algorithms>
<Key>A256KW</Key>
<Content>A256GCM</Content>
</Algorithms>
<SecretKey>
<Value ref="private.key" encoding="hex"/>
</SecretKey>
<Subject>subject-subject</Subject>
<Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
<Audience>audience1,audience2</Audience>
<ExpiresIn>8h</ExpiresIn>
<AdditionalClaims>
<Claim name="additional-claim-name" type="string">additional-claim-value-goes-here</Claim>
</AdditionalClaims>
<OutputVariable>session-token</OutputVariable>
</GenerateJWT>
I'm SORRY! I gave the wrong configuration above. The encoding
attribute needs to be on the SecretKey element. You should use THIS:
<SecretKey encoding='hex'>
<Value ref='private.key' />
</SecretKey>
I am using Apigee X
I used the encoding config too in my earlier comment 🙂
But yes, with new configuration it works fine. Thankyou 🙂
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<GenerateJWT async="false" continueOnError="false" enabled="true" name="Generate-JWT-UsingA256KW-A256GCM">
<DisplayName>Generate JWT-UsingA256KW-A256GCM</DisplayName>
<Algorithms>
<Key>A256KW</Key>
<Content>A256GCM</Content>
</Algorithms>
<SecretKey encoding="hex">
<Value ref="private.key"/>
</SecretKey>
<Subject>subject-subject</Subject>
<Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
<Audience>audience1,audience2</Audience>
<ExpiresIn>8h</ExpiresIn>
<AdditionalClaims>
<Claim name="additional-claim-name" type="string">additional-claim-value-goes-here</Claim>
</AdditionalClaims>
<OutputVariable>jwt-variable</OutputVariable>
</GenerateJWT>
@dchiesa1 Thanks for clarifying. Now it is working.