Reputation: 5927
I'm trying to create the access token using box app user id. I have use the following code to create the box app user
curl https://api.box.com/2.0/users \
-H "Authorization: Bearer <TOKEN>" \
-d '{"name": "Ned Stark", "is_platform_access_only": true}' \
-X POST
Then it is give the following result
{"type":"user","id":"2199107004","name":"Ned Stark","login":"[email protected]","created_at":"2017-08-03T00:58:04-07:00"
Is it possible to generate the access token using box app user id.?
Edited
I have generate the Public key in BOX API. Then I have file which is having Public key and Private key detail like as bellow,
{
"boxAppSettings": {
"clientID": <Client ID>,
"clientSecret": <clientsecret>,
"appAuth": {
"publicKeyID": <publickeyid>,
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\Key heresn-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": <phrase>
}
},
"enterpriseID": <enterpriseId>
}
Then I have generate header and payload, which is as follow
$header = ["typ"=> "JWT", "alg"=>"RS256","kid"=> <public key id>];
$payload = [
"iss"=> "<client id>",
"sub"=> "<APP USER ID>",
"box_sub_type"=> "user",
"aud"=>"https://api.box.com/oauth2/token",
"jti"=>"<I don't know what is this>",
"exp"=>1428699385
];
$header = base64_encode(json_encode($header));
$payload = base64_encode(json_encode($payload));
After this I got stuck how to implement the private and public key here. Actually I'm having the JSON file which is downloaded from BOX API.
And I can't understand what is the JTI
? How to add the public key and|or private key JSON file in this? How to do it?
And I have generate the private key manually as per document, as follow
openssl genrsa -aes256 -out private_key.pem 2048
Then I gave the password as "12345". And generate public key as follow,
openssl rsa -pubout -in private_key.pem -out public_key.pem
Then I added the public key in BOX-API and I made a code as follow,
$data = file_get_contents('private_key.pem');
$result = openssl_pkey_get_private($data,"12345");
print_r($result);
It gives the following result
Resource id #4
These is not looking like encrypted data. And how to implement private and public when calling box api in php.?
Upvotes: 14
Views: 1961
Reputation: 96
I won't recommend you to implement this yourself since there are already a couple of libraries implementing this protocol. However I split my answer into 2 parts the first part explains how to use an open source package to solve your problem, the second part helps you out if you want to do private keys signing.
There are a couple of php packages that support JWT signing, at the moment of writing the one that is used most is lcobucci/jwt, but there are also other implementations found here: https://packagist.org/search/?q=jwt
You can use composer to install it. Since version 4.0 is not documented right now I suggest you install 3.2 and have a look at the README file of that version.
You can require this in your project using: composer require lcobucci/jwt:^3.2
Your code sample suggests you need RSA256, the library has an example for that:
<?php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys
$signer = new Sha256();
$keychain = new Keychain();
$token = (new Builder())
->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"
->sign($signer, $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key
->getToken(); // Retrieves the generated token
When using public and private keys you always have to be sure to keep your private key safe. You can however easily publish your public key to the world without compromising security.
Signing is done using the private key, since you don't want people to be able to fake your signature, signing with the public part would make it possible for everyone to do it. This also means that the verify step always uses the public key, because everyone should be able to do it.
The code example you provided simply loads a private key, but does not do any action with it. In order to sign you will need to use openssl_sign
with your variable. Resource #xx
simply means a reference to something external in php.
<?php
// Data to sign
$payload = 'TEST';
// Generate a new key, load with: openssl_pkey_get_private
$privateKey = openssl_pkey_new(array('private_key_bits' => 512)); // NOT SECURE BUT FAST
// Extract public part from private key
$details = openssl_pkey_get_details($privateKey);
// Use openssl_pkey_get_public to load from file
$publicKey = $details['key'];
// Generated by openssl_sign
$signature = null;
// Sign with private key
openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// Use base64 because the signature contains binairy data
echo 'Signed data: '.base64_encode($signature).PHP_EOL;
// Use publicKey to verify signature
$valid = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo 'Signature is '.($valid ? 'Valid' : 'Invalid').PHP_EOL;
If you still want to implement the complete protocol I suggest you have another look at the package. And as already suggested by the comments the complete specification:
https://www.rfc-editor.org/rfc/rfc7519.txt
Last hint: JWT uses some different characters for base64 than php so be sure to handle that correctly.
Upvotes: 3