static function lookupByToken($token) { //Expecting well formatted token see getAuthToken routine for details. $matches = array(); if (!preg_match(static::$token_regex, $token, $matches)) { return null; } //Unpack the user and ticket ids $matches += unpack('Vuid/Vtid', Base32::decode(strtolower(substr($matches['hash'], 0, 13)))); $user = null; switch ($matches['type']) { case 'c': //Collaborator c if (($user = Collaborator::lookup($matches['uid'])) && $user->getTicketId() != $matches['tid']) { $user = null; } break; case 'o': //Ticket owner if ($ticket = Ticket::lookup($matches['tid'])) { if (($user = $ticket->getOwner()) && $user->getId() != $matches['uid']) { $user = null; } } break; } if (!$user || !$user instanceof TicketUser || strcasecmp($user->getAuthToken($matches['algo']), $token)) { return false; } return $user; }
/** * Generates a (semi-)random Secret Key for TOTP generation * * @return string */ public function generateSecret() { $secret = ""; for ($i = 1; $i <= $this->secretLength; $i++) { $c = rand(0, 255); $secret .= pack("c", $c); } return $this->base32->encode($secret); }
public static function hashFromPublicKey($publicKey) { // Convert PEM to DER encoding before hashing with SHA-1. $string_start = '-----BEGIN PUBLIC KEY-----'; $string_end = '-----END PUBLIC KEY-----'; $pem = substr($publicKey, strpos($publicKey, $string_start) + strlen($string_start), (strlen($publicKey) - strpos($publicKey, $string_end)) * -1); $der = base64_decode($pem); $der = substr($der, 22, strlen($der)); // We skip the first 22 bytes. // We only use the first half of the hash. $sha = substr(sha1($der), 0, 20); $onion_hash = Base32::encode(hex2bin($sha)); return strtolower($onion_hash); }
public function fetch() { $rs = $this->_fetch(); $ret = array(); foreach ($rs as $r) { $match = NULL; $btih = ''; preg_match('([0-9A-Z]{32})', $r['enclosure'], $match); if ($match) { $btih = hexdump(Base32::decode($match[0])); } if ($btih == '') { LOGW("无法解析资源的 BTIH, r = " . var_export($r, TRUE)); } $ret[] = array('btih' => $btih, 'title' => $r['title'], 'guid' => $r['guid'], 'link' => $r['link'], 'description' => $r['description'], 'pubDate' => strtotime($r['pubDate']), 'magnet' => $r['enclosure']); } return $ret; }
public static function decode($input) { if (!self::$ralphabet) { self::$ralphabet = array_flip(self::$alphabet); } $output = 0; $l = strlen($input); for ($n = 0; $n < $l; $n++) { $c = $input[$n]; echo "c = {$c}, l = {$n}, output = {$output}\n"; $output *= 32; if (isset(self::$ralphabet[$c])) { $output += self::$ralphabet[$c]; } else { return false; } } echo "c = {$c}, l = {$l}, output = {$output}\n"; return $output; }
public static function create($db, $class = '') { $params = func_get_args(); array_shift($params); array_shift($params); $class = strtolower(trim($class)); if (!strlen($class)) { $class = 'null'; } if (!isset(self::$classmap[$class])) { trigger_error('Asset::create(): object class "' . $class . '" does not exist', E_USER_ERROR); return null; } $className = self::$classmap[$class]; $db->insert('asset_object', array('object_class' => $class, '@object_created' => $db->now(), '@object_modified' => $db->now(), 'object_has_manifest' => false)); $id = $db->insertId(); $key = Base32::encode($id); $db->update('asset_object', array('object_key' => $key), array('object_id' => $id)); echo 'Created new asset of class "' . $class . '" with key "' . $key . '"' . "\n"; call_user_func_array(array($className, 'createObject'), array($db, $key, $params)); return self::get($db, $key); }
/* Copyright 2009 Mo McRoberts. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) of this software may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AUTHORS OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ require dirname(__FILE__) . '/../lib/common.php'; array_shift($argv); foreach ($argv as $value) { echo $value . " = " . Base32::encode($value) . "\n"; }
/** * Check the verification code entered by the user. */ function verify($secretkey, $thistry, $relaxedmode, $lasttimeslot) { // Did the user enter 6 digits ? if (strlen($thistry) != 6) { return false; } else { $thistry = intval($thistry); } // If user is running in relaxed mode, we allow more time drifting // ±4 min, as opposed to ± 30 seconds in normal mode. if ($relaxedmode == 'enabled') { $firstcount = -8; $lastcount = 8; } else { $firstcount = -1; $lastcount = 1; } $tm = floor(time() / 30); $secretkey = Base32::decode($secretkey); // Keys from 30 seconds before and after are valid aswell. for ($i = $firstcount; $i <= $lastcount; $i++) { // Pack time into binary string $time = chr(0) . chr(0) . chr(0) . chr(0) . pack('N*', $tm + $i); // Hash it with users secret key $hm = hash_hmac('SHA1', $time, $secretkey, true); // Use last nipple of result as index/offset $offset = ord(substr($hm, -1)) & 0xf; // grab 4 bytes of the result $hashpart = substr($hm, $offset, 4); // Unpak binary value $value = unpack("N", $hashpart); $value = $value[1]; // Only 32 bits $value = $value & 0x7fffffff; $value = $value % 1000000; if ($value === $thistry) { // Check for replay (Man-in-the-middle) attack. // Since this is not Star Trek, time can only move forward, // meaning current login attempt has to be in the future compared to // last successful login. if ($lasttimeslot >= $tm + $i) { error_log("Google Authenticator plugin: Man-in-the-middle attack detected (Could also be 2 legit login attempts within the same 30 second period)"); return false; } // Return timeslot in which login happened. return $tm + $i; } } return false; }
/** * RFC 4648 Base32-Hex decoding * * "CPNMU===" -> "foo" * * @param string $str * @return string */ public function base32HexDecode(string $str) : string { return Base32::decodeUpper($str, true); }
if ($min_errorLogger) { require_once 'Minify/Logger.php'; if (true === $min_errorLogger) { require_once 'FirePHP.php'; $min_errorLogger = FirePHP::getInstance(true); } Minify_Logger::setLogger($min_errorLogger); } // check for URI versioning if (preg_match('/&\\d/', $_SERVER['QUERY_STRING'])) { $min_serveOptions['maxAge'] = 31536000; } // Base32 Decode URL Components if ($min_encodeURL) { include '../system/library/base32.php'; $base32_encode = new Base32(); $parts = explode('/', str_replace($_SERVER['REQUEST_QUERY'], '', $_SERVER['REQUEST_URI'])); $fbase = $base32_encode->toString($parts[count($parts) - 2]); if (substr($fbase, 0, 2) == 'f=') { $_GET['f'] = str_replace('f=', '', $fbase); } $bbase = $base32_encode->toString($parts[count($parts) - 3]); if (substr($bbase, 0, 2) == 'b=') { $_GET['b'] = str_replace('b=', '', $bbase); } } if (isset($_GET['f'])) { $_GET['f'] = str_replace("", '', (string) $_GET['f']); } if (isset($_GET['b'])) { $_GET['b'] = str_replace("", '', (string) $_GET['b']);
function otpenable() { require_once "lib/otphp/vendor/base32.php"; require_once "lib/otphp/lib/otp.php"; require_once "lib/otphp/lib/totp.php"; $password = $_REQUEST["password"]; $otp = $_REQUEST["otp"]; $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]); if ($authenticator->check_password($_SESSION["uid"], $password)) { $result = $this->dbh->query("SELECT salt\n\t\t\t\tFROM ttrss_users\n\t\t\t\tWHERE id = " . $_SESSION["uid"]); $base32 = new Base32(); $secret = $base32->encode(sha1($this->dbh->fetch_result($result, 0, "salt"))); $topt = new \OTPHP\TOTP($secret); $otp_check = $topt->now(); if ($otp == $otp_check) { $this->dbh->query("UPDATE ttrss_users SET otp_enabled = true WHERE\n\t\t\t\t\tid = " . $_SESSION["uid"]); print "OK"; } else { print "ERROR:" . __("Incorrect one time password"); } } else { print "ERROR:" . __("Incorrect password"); } }
function authenticate($login, $password) { $pwd_hash0 = hash_password($password); $pwd_hash1 = encrypt_password($password); $pwd_hash2 = encrypt_password($password, $login); $login = db_escape_string($login); $otp = db_escape_string($_REQUEST["otp"]); if (get_schema_version() > 96) { if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { $result = db_query("SELECT otp_enabled,salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'"); if (db_num_rows($result) > 0) { require_once "lib/otphp/vendor/base32.php"; require_once "lib/otphp/lib/otp.php"; require_once "lib/otphp/lib/totp.php"; $base32 = new Base32(); $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled")); $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt"))); $topt = new \OTPHP\TOTP($secret); $otp_check = $topt->now(); if ($otp_enabled) { if ($otp) { if ($otp != $otp_check) { return false; } } else { $return = urlencode($_REQUEST["return"]); ?> <html> <head><title>Tiny Tiny RSS</title></head> <?php echo stylesheet_tag("css/utility.css"); ?> <body class="otp"><div class="content"> <form action="public.php?return=<?php echo $return; ?> " method="POST" class="otpform"> <input type="hidden" name="op" value="login"> <input type="hidden" name="login" value="<?php echo htmlspecialchars($login); ?> "> <input type="hidden" name="password" value="<?php echo htmlspecialchars($password); ?> "> <input type="hidden" name="bw_limit" value="<?php echo htmlspecialchars($_POST["bw_limit"]); ?> "> <input type="hidden" name="remember_me" value="<?php echo htmlspecialchars($_POST["remember_me"]); ?> "> <input type="hidden" name="profile" value="<?php echo htmlspecialchars($_POST["profile"]); ?> "> <label><?php echo __("Please enter your one time password:"******"off" size="6" name="otp" value=""/> <input type="submit" value="Continue"/> </form></div> <script type="text/javascript"> document.forms[0].otp.focus(); </script> <?php exit; } } } } } $result = db_query("SELECT id,pwd_hash FROM ttrss_users WHERE\n\t\t\tlogin = '******'"); if (db_num_rows($result) === 1) { if (version_compare(PHP_VERSION, '5.5.0', '<')) { require_once 'vendor/ircmaxell/password-compat/lib/password.php'; } $pwd_hash_dp = db_fetch_result($result, 0, "pwd_hash"); if (password_verify($password, $pwd_hash_dp)) { return db_fetch_result($result, 0, "id"); } } if (get_schema_version() > 87) { $result = db_query("SELECT salt FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'"); if (db_num_rows($result) !== 1) { return false; } $salt = db_fetch_result($result, 0, "salt"); if ($salt == "") { $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; // verify and upgrade password to new salt base $result = db_query($query); if (db_num_rows($result) === 1) { // upgrade password to MODE2 $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); db_query("UPDATE ttrss_users SET\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'"); $query = "SELECT id\n\t\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } else { return false; } } else { $pwd_hash = encrypt_password($password, $salt, true); $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } } else { $query = "SELECT id\n\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; } $result = db_query($query); if (db_num_rows($result) === 1) { // Authentication was successful, but the hash in the database // is not secure. We need to update it. db_query("UPDATE ttrss_users SET\n\t\t\t\tpwd_hash = '{$pwd_hash0}' WHERE login = '******'"); return db_fetch_result($result, 0, "id"); } return false; }
public function minifyCSS($output) { global $vqmod; global $config; require_once DIR_SYSTEM . 'library/base32.php'; $css_pattern = '~<link rel="stylesheet" type="text\\/css" href="(.*?\\.css)".*?\\/?>~i'; $all_css_scripts = array(); $css_excludes = array(); $dir_include = ''; $cdn_css = ''; $base32_encode = new Base32(); if ($config->get('config_cdn_status') && $config->get('config_cdn_css')) { // SETUP CDN URLS $cdn_css = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1') ? $config->get('config_cdn_https') : $config->get('config_cdn_http'); } $parsed_url = parse_url(HTTP_SERVER); if (strlen($parsed_url['path']) > 1) { $dir_include = substr($parsed_url['path'], 1, strlen($parsed_url['path']) - 1); } if (preg_match('~.*<\\/head>~im', $output) && !defined('DIR_CATALOG')) { // IF OUTPUT HAS A HTML HEAD SECTION $header_data_split = preg_split('~<\\/head>~i', $output); $header_data = $header_data_split[0]; $after_header_data = $header_data_split[1]; $match_data = preg_replace('/<!--\\[if.*?\\]>\\s*?.*?<!\\[endif\\]-->/is', '', $header_data); //REMOVE CONDITIONAL DATA $match_data = preg_replace('/<!--.*?-->/is', '', $match_data); //REMOVE COMMENTED DATA $match_data = preg_replace('~<link rel="stylesheet" type="text\\/css" href="http(.*?\\.css)".*?\\/?>~i', '', $match_data); //REMOVE EXTERNAL CSS $match_data = preg_replace('~<link rel="stylesheet" type="text\\/css" href="\\/\\/(.*?\\.css)".*?\\/?>~i', '', $match_data); //REMOVE EXTERNAL JAVASCRIPT $match_data = preg_replace('~\\?v\\=1\\.0\\.11~i', '', $match_data); //SHOPPICA //CSS EXCLUDES $css_exclude = $config->get('config_ipscss_excludes'); if (!empty($css_exclude)) { $css_excludes = explode($css_exclude, ","); foreach ($css_excludes as $csse) { $match_data = preg_replace('~<link rel="stylesheet" type="text\\/css" href=".*?' . trim($csse) . '.*?".*?\\/?>~i', '', $match_data); //REMOVE CUSTOM CSS } } $match_data = preg_replace('~<link rel="stylesheet" type="text\\/css" href="\\/\\/(.*?\\.css)".*?\\/?>~i', '', $match_data); //REMOVE EXTERNAL JAVASCRIPT $css_files = array(); preg_match_all($css_pattern, $match_data, $matches, PREG_OFFSET_CAPTURE); foreach ($matches[1] as $match) { $css_files[] = $match[0]; } $css_base = $this->getCommonPath($css_files); foreach ($css_files as $key => $cssfile) { if (!empty($css_base)) { $css_base = substr($css_base, -1) == '/' ? substr($css_base, 0, -1) : $css_base; //REMOVE TRAILING SLASH IF EXISTING $css_files[$key] = str_replace($css_base . '/', '', $cssfile); } $header_data = preg_replace('~<link rel="stylesheet" type="text\\/css" href="' . str_replace('/', '\\/', $cssfile) . '".*?/?>~i', '', $header_data); } if ($css_files) { //IF WE HAVE CSS FILES TO COMBINE if ($config->get('config_minify_encode_url')) { $css_combined = $cdn_css . '/' . $dir_include . 'min/' . (strlen($css_base . $dir_include) ? $base32_encode->toBase('b=' . $dir_include . $css_base) . '/' : '') . $base32_encode->toBase('f=' . implode(array_unique($css_files), ',')) . '/combined.css'; } else { $css_combined = $cdn_css . '/' . $dir_include . 'min/index.php?' . (strlen($css_base . $dir_include) ? 'b=' . $dir_include . $css_base . '&' : '') . 'f=' . implode(array_unique($css_files), ','); } $header_data = preg_replace('~</title>~', '</title>' . "\n" . '<link type="text/css" rel="stylesheet" href="' . $css_combined . '" media="all" />', $header_data); } return $header_data . '</head>' . $after_header_data; } else { return $output; } }
function moveAndWriteFile($hashToUse,$targetDirectory,$fileArray) { $base32String=Base32::encode($fileArray['name'].'|'.$fileArray['type']); move_uploaded_file($fileArray['tmp_name'],$targetDirectory.'/'.$hashToUse.$base32String); }
/** * RFC 4648 Base32 decoding * * @param $str * @return string */ public static function base32DecodeUpper(string $str) : string { return Base32::decodeUpper($str); }
#!/usr/bin/php -q <?php require_once 'PHPOTP.php'; require_once 'Base32.php'; $OTP = new PHPOTP(); $Secret = $OTP->GenSeed(); $Base32Secret = Base32::Encode($Secret); echo 'Secret (Base32): ' . $Base32Secret . "\n"; echo 'HOTP: ' . $OTP->HOTP($Secret) . "\n"; echo 'TOTP: ' . $OTP->TOTP($Secret) . "\n"; echo $OTP->HOTPAsURI('The Issuer', 'A Label', $Base32Secret, 0) . "\n"; echo $OTP->TOTPAsURI('The Issuer', 'A Label', $Base32Secret) . "\n";
/** * Returns the binary value of the base32 encoded secret * @access private * This method should be private but was left public for * phpunit tests to work. * @return binary secret key */ public function byteSecret() { return \Base32::decode($this->secret); }
/** * 解码 * * @param string $input * @return string */ public static function decode($input) { Base32::init(); return Base32::$base32->decode($input); }
')){ window.location = '<?php print add_query_arg(array('tfa_priv_key_reset' => 1, 'settings-updated' => 'true')); ?> '; }">reset</a> ) </p> <h3 class="normal" style="cursor: default">Base32</h3> <p><?php _e('Base32 is used by some third party apps like Google Authenticator. This is just as secret as the key in plain text.', TFA_TEXT_DOMAIN); ?> </p> <p><strong><?php _e('Your private key in base32 is', TFA_TEXT_DOMAIN); ?> </strong>: <?php print Base32::encode($tfa_priv_key); ?> </p> <h3 class="normal" style="cursor: default"><?php _e('Algorithm Used', TFA_TEXT_DOMAIN); ?> </h3> <form method="post" action="<?php print add_query_arg('settings-updated', 'true', $_SERVER['REQUEST_URI']); ?> "> <h2><?php _e('Choose Algorithm', TFA_TEXT_DOMAIN); ?> </h2>
public function testEncodeEmptyString() { // RFC test vectors say that empty string returns empty string $this->assertEquals('', Base32::encode('')); }
function getUIDFromEmailReference($ref) { $info = unpack('Vtid/Vuid', Base32::decode(strtolower(substr($ref, -13)))); if ($info && $info['tid'] == $this->getId()) { return $info['uid']; } }
/** * @throws \InvalidArgumentException * * @return string */ private function getDecodedSecret() { $secret = Base32::decode($this->getSecret()); return $secret; }
function otpqrcode() { require_once "lib/otphp/vendor/base32.php"; require_once "lib/otphp/lib/otp.php"; require_once "lib/otphp/lib/totp.php"; require_once "lib/phpqrcode/phpqrcode.php"; $result = db_query($this->link, "SELECT login,salt,otp_enabled\n\t\t\tFROM ttrss_users\n\t\t\tWHERE id = " . $_SESSION["uid"]); $base32 = new Base32(); $login = db_fetch_result($result, 0, "login"); $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled")); if (!$otp_enabled) { $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt"))); $topt = new \OTPHP\TOTP($secret); print QRcode::png($topt->provisioning_uri($login)); } }
if ($Result === $Key) { echo 'PASS'; } else { echo "FAIL ('" . $Key . "')"; } echo "\n"; } echo "\nBase32 Encode/Decode Excercise"; $Passes = 100; $MaxLen = 100; $Failures = 0; mt_srand(); for ($i = 0; $i < $Passes; $i++) { $RandStr = ''; $Len = mt_rand(0, $MaxLen); for ($Leni = 0; $Leni < $Len; $Leni++) { $RandStr .= chr(mt_rand(0, 255)); } $Encoded = Base32::Encode($RandStr); $Decoded = Base32::Decode($Encoded); if ($Decoded != $RandStr) { echo "\nFAIL\n"; echo "Input:\t\t " . DumpBinStr($RandStr) . "\n"; echo "Encoded:\t " . $Encoded . "\n"; echo "Decoded:\t " . DumpBinStr($Decoded) . "\n"; $Failures++; } } if ($Failures == 0) { echo ": PASS\n"; }
function authenticate($login, $password) { $pwd_hash1 = encrypt_password($password); $pwd_hash2 = encrypt_password($password, $login); $login = db_escape_string($login); $otp = db_escape_string($_REQUEST["otp"]); if (get_schema_version($this->link) > 96) { if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'"); if (db_num_rows($result) > 0) { require_once "lib/otphp/vendor/base32.php"; require_once "lib/otphp/lib/otp.php"; require_once "lib/otphp/lib/totp.php"; $base32 = new Base32(); $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled")); $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt"))); $topt = new \OTPHP\TOTP($secret); $otp_check = $topt->now(); if ($otp_enabled) { if ($otp) { if ($otp != $otp_check) { return false; } } else { $return = urlencode($_REQUEST["return"]); ?> <html> <head><title>Tiny Tiny RSS</title></head> <body> <form action="public.php?return=<?php echo $return; ?> " method="POST"> <input type="hidden" name="op" value="login"> <input type="hidden" name="login" value="<?php echo htmlspecialchars($login); ?> "> <input type="hidden" name="password" value="<?php echo htmlspecialchars($password); ?> "> <label><?php echo __("Please enter your one time password:"******"password" size="6" name="otp"/> <input type="submit" value="Continue"/> </form> <script type="text/javascript"> document.forms[0].otp.focus(); </script> <?php exit; } } } } } if (get_schema_version($this->link) > 87) { $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'"); if (db_num_rows($result) != 1) { return false; } $salt = db_fetch_result($result, 0, "salt"); if ($salt == "") { $query = "SELECT id\n\t FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; // verify and upgrade password to new salt base $result = db_query($this->link, $query); if (db_num_rows($result) == 1) { // upgrade password to MODE2 $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); db_query($this->link, "UPDATE ttrss_users SET\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'"); $query = "SELECT id\n\t\t FROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } else { return false; } } else { $pwd_hash = encrypt_password($password, $salt, true); $query = "SELECT id\n\t\t FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } } else { $query = "SELECT id\n\t FROM ttrss_users WHERE\n\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; } $result = db_query($this->link, $query); if (db_num_rows($result) == 1) { return db_fetch_result($result, 0, "id"); } return false; }
/** * Generate hash to check. * * Generates a two-factor hash based on key and time which can then be compared to the value entered. * * @since 1.2.0 * * @access private * * @param string $key the key to encode * @param mixed $time timestamp * * @return string the hash */ private function get_code( $key, $time = false ) { require_once( dirname( __FILE__ ) . '/lib/base32.php' ); $base = new Base32(); $secret = $base->toString( $key ); if ( false === $time ) { $time = floor( time() / 30 ); } $timestamp = pack( 'N*', 0 ) . pack( 'N*', $time ); $hash = hash_hmac( 'sha1', $timestamp, $secret, true ); $offset = ord( $hash[19] ) & 0xf; $code = ( ( ( ord( $hash[ $offset + 0 ] ) & 0x7f ) << 24 ) | ( ( ord( $hash[ $offset + 1 ] ) & 0xff ) << 16 ) | ( ( ord( $hash[ $offset + 2 ] ) & 0xff ) << 8 ) | ( ord( $hash[ $offset + 3 ] ) & 0xff ) ) % pow( 10, 6 ); return str_pad( $code, 6, '0', STR_PAD_LEFT ); }
/** * Check the verification code entered by the user. */ function verify($secretkey, $thistry, $relaxedmode) { // Did the user enter 6 digits ? if (strlen($thistry) != 6) { return false; } else { $thistry = intval($thistry); } // If user is running in relaxed mode, we allow more time drifting // ±4 min, as opposed to ± 30 seconds in normal mode. if ($relaxedmode == 'enabled') { $firstcount = -8; $lastcount = 8; } else { $firstcount = -1; $lastcount = 1; } $tm = floor(time() / 30); $secretkey = Base32::decode($secretkey); // Keys from 30 seconds before and after are valid aswell. for ($i = $firstcount; $i <= $lastcount; $i++) { // Pack time into binary string $time = chr(0) . chr(0) . chr(0) . chr(0) . pack('N*', $tm + $i); // Hash it with users secret key $hm = hash_hmac('SHA1', $time, $secretkey, true); // Use last nipple of result as index/offset $offset = ord(substr($hm, -1)) & 0xf; // grab 4 bytes of the result $hashpart = substr($hm, $offset, 4); // Unpak binary value $value = unpack("N", $hashpart); $value = $value[1]; // Only 32 bits $value = $value & 0x7fffffff; $value = $value % 1000000; if ($value == $thistry) { return true; } } return false; }
public function testEncoding() { $random_bytes = \random_bytes(31); // Backwards compatibility: $encoder = Halite::chooseEncoder(false); $this->assertSame(Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(true); $this->assertSame(null, $encoder); // New encoding in version 3: $encoder = Halite::chooseEncoder(Halite::ENCODE_HEX); $this->assertSame(Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE32); $this->assertSame(Base32::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE32HEX); $this->assertSame(Base32Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64); $this->assertSame(Base64::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64URLSAFE); $this->assertSame(Base64UrlSafe::encode($random_bytes), $encoder($random_bytes)); }