apigee / iloveapis2015-jwt-jwe-jws

Apache License 2.0
30 stars 36 forks source link

Private key for JWE #3

Closed EpsteinsMutha closed 9 years ago

EpsteinsMutha commented 9 years ago

The JWT-Signed worked great! However I'm having problems with JWT-Encrypted. The "validate" always gives me "The token is invalid or expired". The trace shows a NullPointerException at JWT_Encrypted_Validator_Callout.java:169, which seems to be where the PKCS8Key object is created.

I used my own public / private key pair, but I'm wondering if I am loading the private key into the vault properly. Is this basically what the API call for creating the vault entry should look like?:

POST https://HOST/v1/organizations/ORG/environments/ENV/vaults/privateKeysByApp/entries { "name": "CAPBAs...gyC0WC", "value": "-----BEGIN PRIVATE KEY----- MIIIAhiG...vZ+MI6YwU=-----END PRIVATE KEY-----" }

(where "..." denotes characters deleted). Basically, I'm wondering if the BEGIN and END PRIVATE KEY portions should be there. I did try removing them as well, but the result was the same.

vinit4u16 commented 9 years ago

Hi,

As mentioned in the read me you need to base64 encode your key and store it with your client_id as name. See below - "a Vault entry needs to be added to the above vault with name = client_id (apikey) and value = private key (base64 encoded)."

I hope this helps.

-Vinit

EpsteinsMutha commented 9 years ago

I see. Thanks, Vinit. I guess since a PEM key is already Base64-encoded, I didn't realize it needed to be encoded again, but that does make sense.

Once I made that change, I was still getting the same error, but I figured it out that it was because I don't have a password on my private key. That was causing this line to assign passwd as null (_JWT_Encrypted_ValidatorCallout.java #135)... String passwd = getPrivateKeyPassword(msgCtxt); ...which later caused the NullPointerException when we did this... PKCS8Key pkcs8 = new PKCS8Key( keyBytes, passwd.toCharArray() ); ..so I added a null check at line 136, and now it works great...

String passwd = getPrivateKeyPassword(msgCtxt);
if (passwd==null) {
    passwd = "";
}

Thanks for the help!

DinoChiesa commented 9 years ago

Just as a side comment - I've updated the code so that it now no longer base64-encodes the private key. However, due to some irregularities with the cURL interface for Vault, the PEM-encoded key still needs some encoding, specifically the newlines need to not be present. obviously newlines are not meaningful in the encoded data part of the PEM file, but newlines are significant in the prelude and postlude (postlude? whatever).

So, here's what I did. I provided a provisioning script that loads the private key PEM into the Vault, replacing each newline with the unix pipe character. Also, I modified the Java code that retrieves from the vault, to do the converse replacement. This is all checked in now.