2

Im getting the above error when sending the following body to the Box OAuth /token operation: grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=.............&client_secret=..........&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im81NGFtcGR6In0=.eyJpc3MiOiIyOHRhZmZ0ejhlenhncnI3aTBocmZnMGlteTc2MjRuMyIsInN1YiI6IjU0MjA5MSIsImJveF9zdWJfdHlwZSI6ImVudGVycHJpc2UiLCJhdWQiOiJodHRwczovL2FwaS5ib3guY29tL29hdXRoMi90b2tlbiIsImp0aSI6IjE0NDYyMzA3MTgxMjM0NTYiLCJleHAiOjE0NDYyMzA3NjgsImlhdCI6MTQ0NjIzMDcxOH0=.ANwpzohhFyUmPMw1wh6kM8xzqsUanS3UIdEPN40hvpVDmzI9wS0fTpmxWvudGPPXXmeE0Cr+frbMx+R9V9DvzfJsGv2+mu1bqwsjHwPkOy06IigAvgiJPPFt9CuIdmY/H6pGtDpODfeau77KrT0OJhpQX9He4xy0maS26D7yc/5F3fyxZXHdG/XzTpx88xTpg2HbEJ5ImeZjxkFf6ZH4Un0ZY9TJ3TSEITTcqRxhAUN2qAttnX8H5jmKWyTE5U78+f1LzQz1lPjnQsj/BSRCrF2jkf7N0LfJwq3U1BXNBWiEZRW8wqvaTvZLpiODDsl6VuG/xs1m549wGVwyXCglJQ==

Now the JWT, of the assertion parameter, verifies correctly at jwt.io, and the Public key defined to Box verifies in the Box UI as well at jwt.io.

This indicates to me that what I'm sending is correct.

However Box has an issue..... any help would be very greatly received!

Paul Pogonoski
  • 121
  • 2
  • 10
  • Update: getting no help from any Box staff, I decided to use the .PEM formatted privateKey that is opposite of the public key, instead of the java key store the two were created from. After changing my code to utilise this file I get the same error: { "error": "invalid_grant", "error_description": "OpenSSL unable to verify data: " } It would be good if some Box staff would indicate what their API is doing and expects!! – Paul Pogonoski Nov 07 '15 at 14:39
  • I have tried 4, yes FOUR, ways to generate the signature for my JWT. All of them verify in an independent source, and ALL of them return the error that is the subject of this post. The last was using the BC classes, yet Box still rejects the Signature. I would suggest that box is hardcoding something in their SDK that is not in any other signature and that why an independently generated signature is not verified. BOX needs to help me, or come clean... or both. – Paul Pogonoski Nov 15 '15 at 16:21

4 Answers4

2

The problem seems to be in the public and private key generated using openssl in a DOS command prompt.

You can follow the instructions in this link: https://box-content.readme.io/docs/app-auth

First of all, you have to download Cygwin tool: http://www.cygwin.com/

Then, in the Cygwin console you can launch the following commands:

For the private key

openssl genrsa -aes256 -out private_key.pem 2048

For the public key

openssl rsa -pubout -in private_key.pem -out public_key.pem

Be sure to include the full header and footer: '-----BEGIN PUBLIC KEY-----' AND '-----END PUBLIC KEY-----'

Once you've generated a public key, you will need to add it in your app's configuration. When finished you'll get a Public Key ID.

You should be able to connect with your keys using the Box API.

var privateKey = File.ReadAllText("private_key.pem");

var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID);
var boxJWT = new BoxJWTAuth(boxConfig);

var adminToken = boxJWT.AdminToken();
Console.WriteLine("Admin Token: " + adminToken);

I hope this will help you

  • Firstly, I'm using a Mac and, secondly, as I've posted a number of times, these keys verified independly a number of times. Thirdly, I use you commands to the letter by cutting and pasting them. But lastly, you have confirmed my suspicions by posting code that relies on your SDK, which uses the JOSE4j utilities. I'm running my code in an OSGi container that has older versions of the BC classes, so using your SDK is not possible. If you tested your API with anything other than the JOSE4j utilities you'd have the same problem that I had. – Paul Pogonoski Nov 21 '15 at 10:21
  • Ok, in my case it was not a problem in SDK (we're talking about simple wrappers of calls to the BOX rest services) but in the starch to generate keys. Do not just cut and paste... probably you have to find a specific tool for MAC to generate both the keys, i think. – Massimo Della Calce Nov 22 '15 at 21:43
  • I mean a Unix-like environment and command-line interface as alternative to Cygwin – Massimo Della Calce Nov 23 '15 at 17:04
  • Thanks Massimo. however, whether type the commands or cut and paste, or any means, I still got the error. the ONLY way to avoid it was to use the JOSE4J classes. – Paul Pogonoski Nov 26 '15 at 18:37
1

Right... this is extremely annoying! Despite having created correct JWT's for other Public API's, and having the Header and body of the claim, and the signature verified by jwt.io, THE ONLY WAY to get box to accept my JWT was to use the JOSE4J utilities that the Box SDK uses.

This is really poor BOX - lift your game, and support JWT that are valid, not just the proprietary ones created by the JOSE4J classes!!!

Paul Pogonoski
  • 121
  • 2
  • 10
  • It is annoying that more specific information isn't provided to help troubleshoot and remedy the issue. However, as the author of jose4j and contributor to the RFCs that it implements I'd like to clarify that jose4j is not at all proprietary. If you discover specific defects where it's not adhering to the specifications, please let me know so I can correct them. – Brian Campbell Nov 25 '15 at 18:00
0

The JWT in the example in the question that is the value of the assertion parameter appears to have its parts encoded using regular base64 encoding rather than base64url encoding prescribed by JWT/JWS. Many/most base64 implementations are very liberal in decoding and will happily accept base64 or base64url interchangeably. I'd guess that is why, despite that JWT not technically adhering to the specifications, it verifies okay when used directly at something like jwt.io. However, it might cause problems if not properly encoded when sent in the body of the HTTP request, which is expected to be application/x-www-form-urlencoded. The '+', for example, will decode to a space which will be ignored by many base64 decoders. The description in the error you're seeing doesn't seem to line up with that being the problem but it will corrupt the data and be a problem at some point (unless maybe you are url encoding the parameter values and just showing them unencoded in the question). Using base64url rather than base64 will mean that the value of the assertion parameter doesn't need to be url encoded and won't get messed up during url decoding. And base64url will be compliant with JWT. At least it would let you rule out some potential problems.

Community
  • 1
  • 1
Brian Campbell
  • 2,293
  • 12
  • 13
  • Thanks Brian, good point, however I have base64URL encoded them. All the assertions verify in Box, as you get back specific errors on the claims if it doesn't. In this case these have passed and it is only the signature that is failing. – Paul Pogonoski Nov 26 '15 at 18:35
0

I had exactly the same problem, with the same error message from Box and the JWT verifying correctly in jwt.io.

It turns out that the problem was in Base64 vs Base64Url encoding. As Brian pointed, jwt.io can use both Base64 and Base64Url encoding, but Box requires Base64Url. The framework I am using uses Base64 by default and this was the problem and after forcing Base64Url on all parts of the JWT assertion, Box login succeeded.

mnikolic
  • 572
  • 1
  • 5
  • 9