add methods to decrypt return data from router
[GitHub/Stricted/speedport-hybrid-php-api.git] / CryptLib / Password / Implementation / Blowfish.php
diff --git a/CryptLib/Password/Implementation/Blowfish.php b/CryptLib/Password/Implementation/Blowfish.php
new file mode 100644 (file)
index 0000000..2205286
--- /dev/null
@@ -0,0 +1,195 @@
+<?php
+/**
+ * The Blowfish password hashing implementation
+ *
+ * Use this class to generate and validate Blowfish password hashes.
+ *
+ * PHP version 5.3
+ *
+ * @category   PHPCryptLib
+ * @package    Password
+ * @subpackage Implementation
+ * @author     Anthony Ferrara <ircmaxell@ircmaxell.com>
+ * @copyright  2011 The Authors
+ * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @version    Build @@version@@
+ */
+
+namespace CryptLib\Password\Implementation;
+
+use CryptLib\Random\Factory as RandomFactory;
+
+/**
+ * The Blowfish password hashing implementation
+ *
+ * Use this class to generate and validate Blowfish password hashes.
+ *
+ * @category   PHPCryptLib
+ * @package    Password
+ * @subpackage Implementation
+ * @author     Anthony Ferrara <ircmaxell@ircmaxell.com>
+ */
+class Blowfish implements \CryptLib\Password\Password {
+
+    /**
+     * @var Generator The random generator to use for seeds
+     */
+    protected $generator = null;
+
+    /**
+     * @var int The number of iterations to perform (base 2)
+     */
+    protected $iterations = 10;
+
+    /**
+     * Determine if the hash was made with this method
+     *
+     * @param string $hash The hashed data to check
+     *
+     * @return boolean Was the hash created by this method
+     */
+    public static function detect($hash) {
+        static $regex = '/^\$2[ay]\$(0[4-9]|[1-2][0-9]|3[0-1])\$[a-zA-Z0-9.\/]{53}/';
+        return 1 == preg_match($regex, $hash);
+    }
+
+    /**
+     * Return the prefix used by this hashing method
+     *
+     * @return string The prefix used
+     */
+    public static function getPrefix() {
+        if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
+            return '$2y$';
+        } else {
+            return '$2a$';
+        }
+    }
+
+    /**
+     * Load an instance of the class based upon the supplied hash
+     *
+     * @param string $hash The hash to load from
+     *
+     * @return Password the created instance
+     * @throws InvalidArgumentException if the hash wasn't created here
+     */
+    public static function loadFromHash($hash) {
+        if (!static::detect($hash)) {
+            throw new \InvalidArgumentException('Hash Not Created Here');
+        }
+        list(, , $iterations) = explode('$', $hash, 4);
+        return new static((int) $iterations);
+    }
+
+    /**
+     * Build a new instance
+     *
+     * @param int       $iterations The number of times to iterate the hash
+     * @param Generator $generator  The random generator to use for seeds
+     *
+     * @return void
+     */
+    public function __construct(
+        $iterations = 8,
+        \CryptLib\Random\Generator $generator = null
+    ) {
+        if ($iterations > 31 || $iterations < 4) {
+            throw new \InvalidArgumentException('Invalid Iteration Count Supplied');
+        }
+        $this->iterations = $iterations;
+        if (is_null($generator)) {
+            $random    = new RandomFactory();
+            $generator = $random->getMediumStrengthGenerator();
+        }
+        $this->generator = $generator;
+    }
+
+    /**
+     * Create a password hash for a given plain text password
+     *
+     * @param string $password The password to hash
+     *
+     * @return string The formatted password hash
+     */
+    public function create($password) {
+        /**
+         * Check for security flaw in the bcrypt implementation used by crypt()
+         * @see http://php.net/security/crypt_blowfish.php
+         */
+        $match = preg_match('/[\x80-\xFF]/', $password);
+        if (version_compare(PHP_VERSION, '5.3.7', '<') && $match) {
+            throw new \RuntimeException(
+                'The bcrypt implementation used by PHP contains a security flaw ' .
+                'for password with 8-bit character. We suggest to upgrade to ' .
+                'PHP 5.3.7+ or use passwords with only 7-bit characters'
+            );
+        }
+        $salt       = $this->to64($this->generator->generate(16));
+        $prefix     = static::getPrefix();
+        $prefix    .= str_pad($this->iterations, 2, '0', STR_PAD_LEFT);
+        $saltstring = $prefix . '$' . $salt;
+        $result     = crypt($password, $saltstring);
+        if ($result[0] == '*') {
+            //@codeCoverageIgnoreStart
+            throw new \RuntimeException('Password Could Not Be Created');
+            //@codeCoverageIgnoreEnd
+        }
+        return $result;
+    }
+
+    /**
+     * Verify a password hash against a given plain text password
+     *
+     * @param string $password The password to hash
+     * @param string $hash     The supplied ahsh to validate
+     *
+     * @return boolean Does the password validate against the hash
+     */
+    public function verify($password, $hash) {
+        if (!static::detect($hash)) {
+            throw new \InvalidArgumentException(
+                'The hash was not created here, we cannot verify it'
+            );
+        }
+        $test = crypt($password, $hash);
+        return $test == $hash;
+    }
+
+    /**
+     * Convert the input number to a base64 number of the specified size
+     *
+     * @param int $input The number to convert
+     *
+     * @return string The converted representation
+     */
+    protected function to64($input) {
+        static $itoa = null;
+        if (empty($itoa)) {
+            $itoa = './ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                    . 'abcdefghijklmnopqrstuvwxyz0123456789';
+        }
+        $output = '';
+        $size   = strlen($input);
+        $ictr   = 0;
+        do {
+            $cval1   = ord($input[$ictr++]);
+            $output .= $itoa[$cval1 >> 2];
+            $cval1   = ($cval1 & 0x03) << 4;
+            if ($ictr >= $size) {
+                $output .= $itoa[$cval1];
+                break;
+            }
+            $cval2 = ord($input[$ictr++]);
+            $cval1 |= $cval2 >> 4;
+            $output .= $itoa[$cval1];
+            $cval1   = ($cval2 & 0x0f) << 2;
+            $cval2   = ord($input[$ictr++]);
+            $cval1 |= $cval2 >> 6;
+            $output .= $itoa[$cval1];
+            $output .= $itoa[$cval2 & 0x3f];
+        } while (true);
+        return $output;
+    }
+
+}
\ No newline at end of file