-
-
Save hardevine/95ae7b95ea498e1ed81448e6fb634c55 to your computer and use it in GitHub Desktop.
Revisions
-
Glenn Sjöström created this gist
Oct 13, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,133 @@ <?php class LaravelCookieDecrypter { /** * The encryption key. * * @var string */ protected $key = 'YOUR LARAVEL .ENV APP KEY'; /** * The algorithm used for encryption. * * @var string */ protected $cipher = MCRYPT_RIJNDAEL_128; /** * The mode used for encryption. * * @var string */ protected $mode = MCRYPT_MODE_CBC; /** * The block size of the cipher. * * @var int */ protected $block = 16; protected $stringUtils; /** * LaravelCookieDecrypter constructor. */ public function __construct() { require_once('SecureRandom.php'); require_once('StringUtils.php'); } public function decrypt($payload) { $payload = $this->getJsonPayload($payload); // We'll go ahead and remove the PKCS7 padding from the encrypted value before // we decrypt it. Once we have the de-padded value, we will grab the vector // and decrypt the data, passing back the unserialized from of the value. $value = base64_decode($payload['value']); $iv = base64_decode($payload['iv']); return unserialize($this->stripPadding($this->mcryptDecrypt($value, $iv))); } protected function getJsonPayload($payload) { $payload = json_decode(base64_decode($payload), true); // If the payload is not valid JSON or does not have the proper keys set we will // assume it is invalid and bail out of the routine since we will not be able // to decrypt the given value. We'll also check the MAC for this encryption. if ( ! $payload || $this->invalidPayload($payload)) { var_dump('Invalid data.'); } if ( ! $this->validMac($payload)) { var_dump('MAC is invalid.'); } return $payload; } protected function validMac(array $payload) { $bytes = (new SecureRandom)->nextBytes(16); $calcMac = hash_hmac('sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true); return StringUtils::equals(hash_hmac('sha256', $payload['mac'], $bytes, true), $calcMac); } protected function stripPadding($value) { $pad = ord($value[($len = strlen($value)) - 1]); return $this->paddingIsValid($pad, $value) ? substr($value, 0, $len - $pad) : $value; } protected function mcryptDecrypt($value, $iv) { try { return mcrypt_decrypt($this->cipher, $this->key, $value, $this->mode, $iv); } catch (Exception $e) { var_dump($e->getMessage()); die; } } protected function invalidPayload($data) { return ! is_array($data) || ! isset($data['iv']) || ! isset($data['value']) || ! isset($data['mac']); } protected function paddingIsValid($pad, $value) { $beforePad = strlen($value) - $pad; return substr($value, $beforePad) == str_repeat(substr($value, -1), $pad); } protected function hash($iv, $value) { return hash_hmac('sha256', $iv.$value, $this->key); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,101 @@ <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <[email protected]> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ /** * A secure random number generator implementation. * * @author Fabien Potencier <[email protected]> * @author Johannes M. Schmitt <[email protected]> */ class SecureRandom { private $useOpenSsl; private $seed; private $seedUpdated; private $seedLastUpdatedAt; private $seedFile; /** * Constructor. * * Be aware that a guessable seed will severely compromise the PRNG * algorithm that is employed. * * @param string $seedFile */ public function __construct($seedFile = null) { $this->seedFile = $seedFile; // determine whether to use OpenSSL if ('/' === DIRECTORY_SEPARATOR && PHP_VERSION_ID < 50304) { $this->useOpenSsl = false; } elseif (!function_exists('openssl_random_pseudo_bytes')) { $this->useOpenSsl = false; } else { $this->useOpenSsl = true; } } /** * {@inheritdoc} */ public function nextBytes($nbBytes) { // try OpenSSL if ($this->useOpenSsl) { $bytes = openssl_random_pseudo_bytes($nbBytes, $strong); if (false !== $bytes && true === $strong) { return $bytes; } } // initialize seed if (null === $this->seed) { if (null === $this->seedFile) { throw new \RuntimeException('You need to specify a file path to store the seed.'); } if (is_file($this->seedFile)) { list($this->seed, $this->seedLastUpdatedAt) = $this->readSeed(); } else { $this->seed = uniqid(mt_rand(), true); $this->updateSeed(); } } $bytes = ''; while (strlen($bytes) < $nbBytes) { static $incr = 1; $bytes .= hash('sha512', $incr++.$this->seed.uniqid(mt_rand(), true).$nbBytes, true); $this->seed = base64_encode(hash('sha512', $this->seed.$bytes.$nbBytes, true)); $this->updateSeed(); } return substr($bytes, 0, $nbBytes); } private function readSeed() { return json_decode(file_get_contents($this->seedFile)); } private function updateSeed() { if (!$this->seedUpdated && $this->seedLastUpdatedAt < time() - mt_rand(1, 10)) { file_put_contents($this->seedFile, json_encode(array($this->seed, microtime(true)))); } $this->seedUpdated = true; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,77 @@ <?php class StringUtils { /** * This class should not be instantiated. */ private function __construct() { } /** * Compares two strings. * * This method implements a constant-time algorithm to compare strings. * Regardless of the used implementation, it will leak length information. * * @param string $knownString The string of known length to compare against * @param string $userInput The string that the user can control * * @return bool true if the two strings are the same, false otherwise */ public static function equals($knownString, $userInput) { // Avoid making unnecessary duplications of secret data if (!is_string($knownString)) { $knownString = (string) $knownString; } if (!is_string($userInput)) { $userInput = (string) $userInput; } if (function_exists('hash_equals')) { return hash_equals($knownString, $userInput); } $knownLen = self::safeStrlen($knownString); $userLen = self::safeStrlen($userInput); if ($userLen !== $knownLen) { return false; } $result = 0; for ($i = 0; $i < $knownLen; ++$i) { $result |= (ord($knownString[$i]) ^ ord($userInput[$i])); } // They are only identical strings if $result is exactly 0... return 0 === $result; } /** * Returns the number of bytes in a string. * * @param string $string The string whose length we wish to obtain * * @return int */ public static function safeStrlen($string) { // Premature optimization // Since this cannot be changed at runtime, we can cache it static $funcExists = null; if (null === $funcExists) { $funcExists = function_exists('mb_strlen'); } if ($funcExists) { return mb_strlen($string, '8bit'); } return strlen($string); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ <?php function decrypt_laravel_session() { # Method 1. Autload Laravel into the application. require '/home/vagrant/Code/minside-fjordclub/webroot/bootstrap/autoload.php'; $app = require_once '/home/vagrant/Code/minside-fjordclub/webroot/bootstrap/app.php'; $app->make('Illuminate\Contracts\Http\Kernel')->handle(Illuminate\Http\Request::capture()); $id = (isset($_COOKIE[$app['config']['session.cookie']]) ? $app['encrypter']->decrypt($_COOKIE[$app['config']['session.cookie']]) : null); if ($id) { $app['session']->driver()->setId($id); $app['session']->driver()->start(); $user_id = $app['auth']->driver()->getSession()->get('id'); } # Method 2. Replicate the Laravel Decrypt code. include('includes/laravel/LaravelCookieDecrypter.php'); $laravel_cookie_decrypter = new LaravelCookieDecrypter(); $session_id = $laravel_cookie_decrypter->decrypt($_COOKIE['laravel_session']); // Returns the session_id // Require the session from the database/filesystem/cache etc with the session_id }