Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

checkToken() always return FALSE when using a token from encrypted cookie

Hi All

I'm trying to use the Crypt in Phalcon, which i have set in my multi-module app (#module). I have a function which creates a session and create a cookie with a token value (#session). The startup works fine, but when i would like to evaluate the key and token by $this->security->checkToken (#check) then it fails. if i set $cookies->useEncryption(false). then it works. I have checked the output from $xsrf_cookie->getValue() and it is equal to the $token string value, before encryption, which is set in the cookie. My experience in this field is low so any suggestions and ideas are welcome, thanks in advance.

BR

// #module
...
$di->set('session', function () {
    $session = new SessionAdapter();
    $session->start();
    return $session;
});

$di->set('security', function () {

    $security = new Security();

// Set the password hashing factor to 12 rounds
    $security->setWorkFactor(12);

    return $security;
}, true);

$di->set('cookies', function () {
    $cookies = new Cookies();

    $cookies->useEncryption(true);

    return $cookies;
});

$di->set('crypt', function () {
    $crypt = new Crypt();

    $crypt->setKey('test');

    return $crypt;
});
...
// #session
...
$auth_key_expire = time() + 15 * 60;
$this->session->set('auth', array(
    'id' => $User->id,
    'auth_key' => $this->security->getTokenKey(),
    'auth_key_expire' => $auth_key_expire
    ));
$token = $this->security->getToken();
$this->cookies->set('XSRF-TOKEN', $token, $auth_key_expire)->send();
...
// #check
...
$auth = $this->session->get('auth');
$xsrf_cookie = ($this->cookies->has('XSRF-TOKEN')) ? $this->cookies->get('XSRF-TOKEN') : FALSE;

if($auth != FALSE && $xsrf_cookie != FALSE) {

    $equal_expire = ($auth['auth_key_expire'] == $xsrf_cookie->getExpiration()) ? TRUE : FALSE;
    $xsrf_token = $xsrf_cookie->getValue();
    $valid_token = $this->security->checkToken($auth['auth_key'],$xsrf_token,FALSE);
}

...

The problem is in the crypt key: Phalcon relies on mcrypt. For each algorithm there is a defined set of supported key lengths. In case you use the RIJNDAEL_256, which, I believe, is default, you can use only keys 16, 24 or 32 chars long.

edited Oct '15

I changed the crypt to the same as in the documentation and changed the session to $di->setShared():

...
$di->setShared('session', function () {
            $session = new SessionAdapter();
            $session->start();
            return $session;
        });
...
$di->set('crypt', function () {

            $crypt = new Crypt();

            $crypt->setKey('%31.1e$i86e$f!8jz');

            return $crypt;
        }, true);
...

But $this->security->checkToken() still return FALSE on all requests when the $xsrf_token has been decrypted and then encrypted. I have checked the token before it is inserted into the checkToken($auth['auth_key'],$xsrf_token,FALSE) and it mathces the value and type, before encryption. If i use $cookies->useEncryption(false) then $this->security->checkToken($auth['auth_key'],$xsrf_token,FALSE) return true if they match.

The old title "fails on checkToken()" may have be misleading as checkToken() returns FALSE on all requests when using crypt as described.

Thanks

Hallo: I do not know mcrypt that much, but what I did is to get a random 64 based hex-key from a generator, pack it and use it as key for crypt, and it worked.

Here's where I got the key:

https://asecuritysite.com/encryption/keygen

and here's the code I used:

$hexkey = '2E6D0D5FC25AEB502A4B90F775761A1F'
$crypt = new \Phalcon\Crypt();
$key = pack('H*',$hexkey);
$crypt->setKey($key);

Hope it help's you.



2.5k
Accepted
answer

I have found the problem, the decrypted string returned from the cookie was eg "X2UOuTfs7RW0Fqp�����������������", but my IDE did only show the actual token 'X2UOuTfs7RW0Fqp' in debug mode. So a simple trim($xsrf_token) before checkToken() solved the problem.

Thanks for other suggestions.