Hi there !
First of all thanks for this great library !
I've been watching the PR to bring new way to pass private & public keys: environment var instead of file reference.
This will make me delete a volume that we're using in production to share the keys to all the running container. Passing by the environment file make that much easier 馃憤
So, I updated the composer.json dependency to the following: "lexik/jwt-authentication-bundle": "~2.5".
And my configuration is the following:
parameters.yml
parameters:
jwt.secret_key: '%env(JWT_SECRET_KEY)%'
jwt.public_key: '%env(JWT_PUBLIC_KEY)%'
jwt.pass_phrase: '%env(JWT_PASS_PHRASE)%'
jwt.token_ttl: '%env(JWT_TOKEN_TTL)%'
config.yml
lexik_jwt_authentication:
secret_key: '%jwt.secret_key%'
public_key: '%jwt.public_key%'
pass_phrase: '%jwt.pass_phrase%'
token_ttl: '%jwt.token_ttl%'
JWT_SECRET_KEY=""
JWT_PUBLIC_KEY=""
JWT_PASS_PHRASE=password
JWT_TOKEN_TTL=3600
The error message I have is:
{
"error": {
"code": 500,
"message": "Internal Server Error",
"exception": [
{
"message": "Could not read key resource: error:0906D06C:PEM routines:PEM_read_bio:no start line",
"class": "RuntimeException",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/var/www/html/vendor/namshi/jose/src/Namshi/JOSE/Signer/OpenSSL/PublicKey.php",
"line": 65,
"args": []
},
{
"namespace": "Namshi\\JOSE\\Signer\\OpenSSL",
"short_class": "PublicKey",
"class": "Namshi\\JOSE\\Signer\\OpenSSL\\PublicKey",
"type": "->",
"function": "getKeyResource",
"file": "/var/www/html/vendor/namshi/jose/src/Namshi/JOSE/Signer/OpenSSL/PublicKey.php",
"line": 19,
"args": [
[
"string",
"\"-----BEGIN RSA PRIVATE KEY-----"
],
[
"string",
"password"
]
]
},
{
"namespace": "Namshi\\JOSE\\Signer\\OpenSSL",
"short_class": "PublicKey",
"class": "Namshi\\JOSE\\Signer\\OpenSSL\\PublicKey",
"type": "->",
"function": "sign",
"file": "/var/www/html/vendor/namshi/jose/src/Namshi/JOSE/JWS.php",
"line": 60,
"args": [
[
"string",
"eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoie1widXNlcm5hbWVcIjpcImouZG9lMVwiLFwiZW1haWxcIjpcInJlaWNoZWwuemV0dGFAaG[.......]vc3RDb252ZW50aW9uRHJhZnRBY3Rpb24iLCJDb2xsZWN0aW9uc0NvbnRyb2xsZXI6OnB1dENvbGxlY3Rpb25DbGluaWNzUmF0ZXNBY3Rpb24iLCJFeGNlcHRpb25Db250cm9sbGVyOjpzaG93QWN0aW9uIl0sImV4cCI6IjE1MzA3MTcxMDEiLCJpYXQiOjE1MzA3MTM1MDJ9"
],
[
"string",
"\"-----BEGIN RSA PRIVATE KEY-----"
],
[
"string",
"password"
]
]
},
{
"namespace": "Namshi\\JOSE",
"short_class": "JWS",
"class": "Namshi\\JOSE\\JWS",
"type": "->",
"function": "sign",
"file": "/var/www/html/vendor/lexik/jwt-authentication-bundle/Services/JWSProvider/DefaultJWSProvider.php",
"line": 99,
"args": [
[
"string",
"\"-----BEGIN RSA PRIVATE KEY-----"
],
[
"string",
"password"
]
]
},
]
}
]
}
}
The problem I have is that I don't know how to format the key in the environment var file. A one line format don't work at all. Doing stuff like:
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA487nB+V2ZvM53ZvonSb8\
T6zR3vaZYufa0dsPn[......]F8CAwEAAQ==\
-----END PUBLIC KEY-----"
Or even like:
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA487nB+V2ZvM53ZvonSb8
T6zR3vaZYufa0dsPn[......]F8CAwEAAQ==
-----END PUBLIC KEY-----"
My private & public keys are generated like that. It works fine, since I was able to use them with filepath configuration before. My problem is really about the correct formatting for the keys on the environment var file.
openssl genrsa -passout pass:password -out var/jwt/private.pem -aes256 4096
openssl rsa -passin pass:password -pubout -in var/jwt/private.pem -out var/jwt/public.pem
So, I don't know how to put the keys in there. I feel like I'm close to a solution, but I can't figure it out...
Also looked at the documentation, but nothing useful on there (at least for my case !).
I'll love to update the documentation once a solution is found :)
Thanks a lot in advance fellas !
Hey, glad to have some feedback about that feature, that will help us documenting it.
Does the following solution work in your case https://stackoverflow.com/a/49489260/4363634?
Hi @chalasr thanks for your response !
I did try, and it doesn't works.
Here a little more context.
Here is a quick extract. Simple, nothing strange there, but worth showing.
backend:
build:
context: .
env_file:
- build/env/configuration.env
With the linked stackoverflow topic, here is the result I have for my environment file:
JWT_SECRET_KEY='-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,B4DDC5E81CCB984691F6B678CD30AEFF
5DDzO68lT2k53kbZ4aMapZ0GTXBHIEEvZb+uhk5idCYQw8BN0oE8gEN4FKkfBbrW
2I5raATnb8f3bUfqFWBsLwis6Moqz4FCqWwYJeCrisKnE2xRKqPXUj1XU0rg+W9a
+vRjZDH4KJMmm398y20DfMBTI7dEt/1X0X7aVGPONldNaDAtua+KleRVWdzMT0hO
o0vhS6ba1YHEEVU/YdxzDDE9lxQE0qjxDLTR90FfcCJNkLx2yqM2ztRdpasrnqc0
G4t/E89O2HmJZim1L/sG2aRTB1wKoPgbHzx6gcZ0O8YuTX+w6EgnH37nyvwdmBIc
ZjW8ID1hWADkEGM9exZf0ABdu+1vmn3By2w1skS54uW3qPVAWVwYET8s1++5W+JX
lNrZ2Tb/EfnAqD/VgOmuwuwtLSWK8hrtXKr8pwTtOgdblZpXrVI2mBdbYptHzV83[...]'
I added a dumb debug line on the following file: vendor/lexik/jwt-authentication-bundle/Services/JWSProvider/DefaultJWSProvider.php:create(array $payload, array $header = [])
echo $this->keyLoader->loadKey('private');
die();
And with the previous env file, I give my the following result on PostMan:
'-----BEGIN RSA PRIVATE KEY-----
As you can see, the key is cut, which make it not usable.
The Exception raised is still the same, tho: "message": "Could not read key resource: error:0906D06C:PEM routines:PEM_read_bio:no start line",
I also tested like:
JWT_SECRET_KEY="-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,B4DDC5E81CCB984691F6B678CD30AEFF[....]"
But without any effect, the \n remain, which make the code unable to manipulate the key.
How did you test the code during the development process ? Did you used environment file ?
I believe multi-lines env directly on docker-compose.yml file works fine, with some escaping from the YAML magic. But it does not fit my needs, and can't be ready for production: all need to be on an environment file.
I'll continue to tests some other formatting & dig a bit into the code.
Any feedback is welcome, it's kind of a headache there :)
Original comment, but wrong:
Working solution with code modification
The only things I get to work right now is the following.
env file
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA487nB+V2ZvM53ZvonSb8\nT6z[...]p9\nXPgycVfF3I0dsn+qkcg0rF8CAwEAAQ==\n-----END PUBLIC KEY-----"php code
echo str_replace('\n', PHP_EOL, $_ENV['JWT_PUBLIC_KEY']); // this works: display multilines content & JWT encode / decode worksWithout the ugly
str_replacedebug line, the error is still the same.So ?
Do you think changing the library behaviour on the
KeyLoaderprocess will make sense ?
Or somewhere else on the code ?
Ok, it doesn't work at all, it was a bad interpretation...
app_dev.php debug linesI did add those lines to the app_dev.php file, to do ugly debug & test stuff:
$_ENV['JWT_SECRET_KEY'] = str_replace('\n', PHP_EOL, $_ENV['JWT_SECRET_KEY']);
$_ENV['JWT_PUBLIC_KEY'] = str_replace('\n', PHP_EOL, $_ENV['JWT_PUBLIC_KEY']);
DefaultJWSProvider.php debug linesThe following debug code still in place on the DefaultJWSProvider.php file:
echo "PRIVATE KEY:\n";
echo $_ENV['JWT_SECRET_KEY'];
echo "---";
echo "\nPUBLIC KEY:\n";
echo $_ENV['JWT_PUBLIC_KEY'];
die();
And the result is:
PRIVATE KEY:
"-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,B4DDC5E81CCB984691F6B678CD30AEFF
5DDzO68lT2k53[....]2uezJbEZ9tCPkh3SwwHQv/5lms3tXi9zBA+/mcOPvCy+82xqC4x
-----END RSA PRIVATE KEY-----"---
PUBLIC KEY:
"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA487nB+V2ZvM53ZvonSb8
T6zR3vaZYufa0dsPnp7MxO1PFlMAMwArcHDEhvp1e7CSMCsy0MvS7KM7RvKMq978
pO7CwhJ97I6RC[...]+qkcg0rF8CAwEAAQ==
-----END PUBLIC KEY-----"
Keys are correctly displayed on RAW content, but it's still not working...
I'm out of idea for today :/
New week, new me.
Didn't find any new way to make it works right now :(
Ok, any update or news ? :)
@piteur Your keys are encrypted. Try with a non-encrypted key
@agathver - I don't see the point there.
My keys are encrypted and should stay encrypted. I don't want to use non-encrypted keys, this is madness :)
I worked before the new release with the old-style parameters (with path to certificate file), and the keys were encrypted. And it worked.
Anyway, thanks for your input.
I currently use the base64 encoded version of the certs in my env vars. So in the config I have:
lexik_jwt_authentication:
secret_key: '%env(base64:JWT_PRIVATE_KEY)%'
public_key: '%env(base64:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
This converts the base64 to the original file contents.
To get the value for the env vars, you can use the output of the next command:
$ cat config/jwt/public.pem | base64 | tr -d '\n'
Use some more environment variable processors and use the following:
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
And load it by
# ...
public_key: '%env(file:resolve:JWT_PUBLIC_KEY)%
Note: I did not test this alternative, but it should work.
Hope this helps!
Thanks a lot for the feedback & ideas @TV-productions - I'll give it a shot this week for the base64 approach.
Really appreciate !
I just tried with the base64 approach, and it works! thanks
Also to override the key path config and use the environment vars for test environment only use
lexik_jwt_authentication:
private_key_path: ~
public_key_path: ~
secret_key: '%env(base64:JWT_PRIVATE_KEY)%'
public_key: '%env(base64:JWT_PUBLIC_KEY)%'
@PaddyLock note that the private_key_path and public_key_path options are not necessary and should be removed (as they won't exist anymore in the next major release).
@chalasr thanks, so should we use secret_key and public_key for both a path to a file and/or the raw key data?
exactly! (you should get a proper deprecation notice when setting the key)
Most helpful comment
I currently use the base64 encoded version of the certs in my env vars. So in the config I have:
This converts the base64 to the original file contents.
To get the value for the env vars, you can use the output of the next command:
Alternative
Use some more environment variable processors and use the following:
And load it by
Note: I did not test this alternative, but it should work.
Hope this helps!