firebase / php-jwt

PHP package for JWT
BSD 3-Clause "New" or "Revised" License
9.36k stars 1.26k forks source link

RSA 256 decoding issues #199

Closed dextermb closed 6 years ago

dextermb commented 6 years ago

Hey,

I am attempting to encode and then decode a JWT token using an RSA256 key pair. But no matter what I try I am always getting the DomainException: Unexpected control character found.

I have attempted different methods of generating and fetching keys using PHP's OpenSSL library, but nothing seemed to work. So here's some of the code I am using.

Class constants

const ALGO = 'RS256';
const ALGOS = [ 'HS256', 'HS384', 'HS512', 'RS256' ];

const CONFIG = [
    'digest_alg' => self::ALGO,
    'x509_extensions' => 'v3_ca',
    'req_extensions' => 'v3_req',
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
    'encrypt_key' => true,
    'encrypt_key_cipher' => OPENSSL_CIPHER_3DES
];

generateKeys method internals:

$dn        = array( 'commonName' => 'test' );
$privkey   = openssl_pkey_new(self::CONFIG);
$csr       = openssl_csr_new($dn, $privkey, self::CONFIG);
$cert      = openssl_csr_sign($csr, null, $privkey, 365, self::CONFIG);
$publicKey = openssl_pkey_get_public($cert);
$publicKey = openssl_pkey_get_details($publicKey);

openssl_pkey_export_to_file($privkey, $this->private_key_path);
file_put_contents($this->public_key_path, $publicKey[ 'key' ]);

loadKeys method internals:

$this->private_key = file_get_contents($this->private_key_path);
$this->public_key  = file_get_contents($this->public_key_path);

if (is_bool($this->private_key)) {
    throw new Exception('Unable to load private key');
}

if (is_bool($this->public_key)) {
    throw new Exception('Unable to load public key');
}

return [ $this->private_key, $this->public_key ];

Encoding:

Firebase::encode($this->claims, $this->private_key, self::ALGO);

Decoding:

Firebase::decode($token, $this->private_key, [ self::ALGO ]);

My suspicion is that encoding using RSA256 does not seem to be working properly. Can anyone confirm or deny this?

Notes:

OrRosenblatt commented 6 years ago

@dextermb I'm not sure why you closed the issue, but the same thing happening to me. RSA256 keys doesn't seem to be decoded properly. If you managed to solve the issue, can you please share why it happens and how to solve it?

dextermb commented 6 years ago

There was a dumb mistake elsewhere in the code that I had missed. RSA256 now works as expected for me.

bshaffer commented 6 years ago

@dextermb can you share your dumb mistake in case it's the same one @OrRosenblatt is experiencing?

dextermb commented 6 years ago

I implemented this into Laravel, used $request->header('authorization') but I did not strip Bearer from the token, meaning it was decoding with Bearer <token>.

Completely separate file, didn't think to check it 😢

OrRosenblatt commented 6 years ago

Thank you @dextermb! Apparently it was exactly the same issue, and stripping the Bearer part from the header fixed it 😄

lindelius commented 6 years ago

@dextermb Just FYI, Laravel has a helper method for getting the bearer token

$request->bearerToken();

rejalex commented 3 years ago

Thank you I guess this thread is old, but that dumb mistake from @dextermb saved my day

@dextermb can you share your dumb mistake in case it's the same one @OrRosenblatt is experiencing? Thank you for asking @dextermb on the dumb mistake, 'cause that dumb mistake saved my day.

angwa commented 3 years ago

Hello @dextermb . I can't figure how you solved this problem. I am using core php and not laravel. Any more explanation will be of great help. Thank you