/** * @param int $length * @return string */ public static function generateSecret($length = 20) { $security = new Security(); $full = Base32::encode($security->generateRandomString($length)); return substr($full, 0, $length); }
public static function createFromString($packet, $fromAddress, &$length = null) { if (strlen($packet) < 4) { return false; } // extract id $len = unpack('Nlen', mb_substr($packet, 0, 4, '8bit'))['len']; if (strlen($packet) < 4 + $len + 4) { return false; } $id = rtrim(\Base32\Base32::encode(substr($packet, 4, $len)), '='); // extract addresses $addrCount = unpack('Ncnt', mb_substr($packet, 4 + $len, 4, '8bit'))['cnt']; $packet = mb_substr($packet, 4 + $len + 4, null, '8bit'); $length = 4 + $len + 4; $addresses = []; while ($addrCount-- > 0) { if (($addr = Address::createFromString($packet, $fromAddress, $skip)) !== false) { $addresses[] = $addr; $packet = mb_substr($packet, $skip, null, '8bit'); $length += $skip; } else { $length = null; return false; } } return new self($id, $addresses); }
/** * @param string|null $secret */ private function setSecret($secret) { Assertion::nullOrString($secret, 'The secret must be a string or null.'); if (null === $secret) { $secret = trim(Base32::encode(random_bytes(32)), '='); } $this->parameters['secret'] = $secret; }
/** * Generate a secret code * * @return string */ public function generateSecret() { $secret = ""; for ($i = 1; $i <= $this->secretLength; $i++) { $c = rand(0, 255); $secret .= pack('c', $c); } return Base32::encode($secret); }
public static function generate($ext = '') { // Generate UUIDv4 $bytes = random_bytes(16); $bytes[6] = chr(0x4 << 4 | ord($bytes[6]) & 0xf); $bytes[8] = chr(ord($bytes[8]) & 0x3f | 0x80); $base32 = rtrim(Base32::encode($bytes), '='); $base32 = strtolower($base32); $filename = $base32 . ($ext != '' ? '.' . $ext : ''); return $filename; }
/** * Encoder tests, reverse of the decodes */ public function testEncode() { // RFC test vectors say that empty string returns empty string $this->assertEquals('', Base32::encode('')); // these strings are taken from the RFC $this->assertEquals('MY======', Base32::encode('f')); $this->assertEquals('MZXQ====', Base32::encode('fo')); $this->assertEquals('MZXW6===', Base32::encode('foo')); $this->assertEquals('MZXW6YQ=', Base32::encode('foob')); $this->assertEquals('MZXW6YTB', Base32::encode('fooba')); $this->assertEquals('MZXW6YTBOI======', Base32::encode('foobar')); }
public function tfaEnableAction() { if (!$this->session2FA->secretCode) { $this->session2FA->secretCode = Base32::encode(random_bytes(256)); } $totp = new \OTPHP\TOTP('Zource', $this->session2FA->secretCode); if ($this->getRequest()->isPost()) { $code = $this->getRequest()->getPost('code'); var_dump($totp->verify($code)); } return new ViewModel(['secretCode' => $this->session2FA->secretCode]); }
/** * @param Parser $parser * @return Ipv4|Ipv6|Onion * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange * @throws \Exception */ public function fromParser(Parser $parser) { $buffer = $parser->readBytes(16); $binary = $buffer->getBinary(); if (Onion::MAGIC === substr($binary, 0, strlen(Onion::MAGIC))) { $addr = strtolower(Base32::encode($buffer->slice(strlen(Onion::MAGIC))->getBinary())) . '.onion'; $ip = new Onion($addr); } elseif (Ipv4::MAGIC === substr($binary, 0, strlen(Ipv4::MAGIC))) { $end = $buffer->slice(strlen(Ipv4::MAGIC), 4); $ip = new Ipv4(long2ip($end->getInt())); } else { $addr = []; foreach (str_split($binary, 2) as $segment) { $addr[] = bin2hex($segment); } $addr = implode(":", $addr); $ip = new Ipv6($addr); } return $ip; }
/** * Create an OTP URI for use with Google Authenticator. * * Note that this is not a URI for the QR code used by Google Authenticator. * The URI produced by this method is used as the actual content of the QR * code, and follows a special set of conventions understood by Google * Authenticator, and other OTP apps. * * @param string $type The otp type identifier. * @param string $parameters Additional URI parameters. * @param HotpBasedConfigurationInterface $configuration The OTP configuration. * @param OtpSharedParametersInterface $shared The shared parameters. * @param string $label The label for the account. * @param string|null $issuer The issuer name. * @param boolean|null $issuerInLabel True if legacy issuer support should be enabled by prefixing the label with the issuer name. * * @return string The OTP URI. */ protected function buildUri($type, $parameters, HotpBasedConfigurationInterface $configuration, OtpSharedParametersInterface $shared, $label, $issuer = null, $issuerInLabel = null) { if (null === $issuerInLabel) { $issuerInLabel = false; } if (6 !== $configuration->digits()) { $parameters .= '&digits=' . rawurlencode($configuration->digits()); } if (HotpHashAlgorithm::SHA1() !== $configuration->algorithm()) { $parameters .= '&algorithm=' . rawurlencode($configuration->algorithm()->value()); } $legacyIssuer = ''; if (null !== $issuer) { if ($issuerInLabel) { $legacyIssuer = rawurlencode($issuer) . ':'; } $parameters .= '&issuer=' . rawurlencode($issuer); } return sprintf('otpauth://%s/%s%s?secret=%s%s', rawurlencode($type), $legacyIssuer, rawurlencode($label), rawurlencode(Base32::encode($shared->secret())), $parameters); }
/** * @param string $secret * @return string */ public function getUri(string $secret) : string { $opt = []; $opt['algorithm'] = $this->digest; $opt['digits'] = $this->digits; $opt['secret'] = trim(Base32::encode($secret), '='); $opt['period'] = $this->interval; ksort($opt); $params = str_replace(['+', '%7E'], ['%20', '~'], http_build_query($opt)); return "otpauth://totp/" . rawurlencode($this->label) . "?{$params}"; }
/** * Encode a string to Base32. * * @param $string * @return mixed */ public function toBase32($string) { $encoded = Base32::encode($string); return str_replace('=', '', $encoded); }
/** * @see https://tools.ietf.org/html/rfc6238#appendix-B * @see http://www.rfc-editor.org/errata_search.php?rfc=6238 */ public function testVectorsData() { $totp_sha1 = $this->createTOTP(8, 'sha1', 30, Base32::encode('12345678901234567890')); $totp_sha256 = $this->createTOTP(8, 'sha256', 30, Base32::encode('12345678901234567890123456789012')); $totp_sha512 = $this->createTOTP(8, 'sha512', 30, Base32::encode('1234567890123456789012345678901234567890123456789012345678901234')); return [[$totp_sha1, 59, '94287082'], [$totp_sha256, 59, '46119246'], [$totp_sha512, 59, '90693936'], [$totp_sha1, 1111111109, '07081804'], [$totp_sha256, 1111111109, '68084774'], [$totp_sha512, 1111111109, '25091201'], [$totp_sha1, 1111111111, '14050471'], [$totp_sha256, 1111111111, '67062674'], [$totp_sha512, 1111111111, '99943326'], [$totp_sha1, 1234567890, '89005924'], [$totp_sha256, 1234567890, '91819424'], [$totp_sha512, 1234567890, '93441116'], [$totp_sha1, 2000000000, '69279037'], [$totp_sha256, 2000000000, '90698825'], [$totp_sha512, 2000000000, '38618901'], [$totp_sha1, 20000000000.0, '65353130'], [$totp_sha256, 20000000000.0, '77737706'], [$totp_sha512, 20000000000.0, '47863826']]; }
<?php use cebe\pulse\discover\Address; use cebe\pulse\discover\Device; use cebe\pulse\discover\DiscoveryManager; use cebe\pulse\discover\Packet; require __DIR__ . '/vendor/autoload.php'; $loop = React\EventLoop\Factory::create(); // config // generates a random node ID, should be replaced with a real hash of the TLS cert $id = rtrim(\Base32\Base32::encode(hash('sha256', rand() . microtime(true), true)), '='); $servicePort = rand(1337, 32000); // setup $discoveryManager = new DiscoveryManager($id); $discoveryManager->servicePort = $servicePort; $discoveryManager->start($loop); // TCP Server $socket = new React\Socket\Server($loop); $socket->on('connection', function ($conn) { // $conn->write("Hello there!\n"); // $conn->write("Welcome to this amazing server!\n"); // $conn->write("Here's a tip: don't say anything.\n"); echo "connection from " . $conn->getRemoteAddress() . "\n"; $conn->on('data', function ($data) use($conn) { echo "{$data}\n"; $conn->close(); }); }); $socket->listen($servicePort); $loop->run();
public function __toString() { return Base32::encode($this->value); }
/** * Create a 64 bit secret string * @return string */ private function createSecret() { return Base32::encode(random_bytes(64)); }
public function makeTOTP($provider = null) { /*** * Assign a user a multifactor authentication code * * @param string $provider The provider giving 2FA. * @return array with the status in the key "status", errors in "error" and "human_error", * username in "username", and provisioning data in "uri" ***/ if (empty($this->username)) { $this->getUser(); # We MUST have this properly assigned if (empty($this->username)) { return array('status' => false, 'error' => 'Unable to get user.'); } } if ($this->getSecret() !== false) { return array('status' => false, 'error' => '2FA has already been enabled for this user.', 'human_error' => "You've already enabled 2-factor authentication.", 'username' => $this->username); } try { if (!class_exists('Stronghash')) { require_once dirname(__FILE__) . '/../core/stronghash/php-stronghash.php'; } $salt = Stronghash::createSalt(); require_once dirname(__FILE__) . '/../base32/src/Base32/Base32.php'; $secret = Base32::encode($salt); ## The resulting provisioning URI should now be sent to the user ## Flag should be set server-side indicating the change id pending $l = $this->openDB(); $query = 'UPDATE `' . $this->getTable() . '` SET `' . $this->tmpColumn . "`='{$secret}' WHERE `" . $this->userColumn . "`='" . $this->username . "'"; $r = mysqli_query($l, $query); if ($r === false) { return array('status' => false, 'human_error' => 'Database error', 'error' => mysqli_error($l)); } # The data was saved correctly # Let's create the provisioning stuff! self::doLoadOTP(); $totp = new OTPHP\TOTP($secret); $totp->setDigest($this->getDigest()); $totp->setLabel($this->username); $totp->setIssuer($provider); $uri = $totp->getProvisioningURI($label, $provider); # iPhones don't actually accept the full, valid URI $unsafe_uri = urldecode($uri); $uri_args = explode('?', $unsafe_uri); $iphone_uri = $uri_args[0] . '?'; $iphone_args = array(); $iphone_safe_args = array('secret', 'issuer'); foreach (explode('&', $uri_args[1]) as $paramval) { $pv = explode('=', $paramval); $param = $pv[0]; $val = $pv[1]; if (in_array($param, $iphone_safe_args)) { $iphone_args[] = $param . '=' . $val; } } $iphone_uri .= implode('&', $iphone_args); /* $iphone32 = str_replace("=","",$secret_part[1]); */ /* $iphone_uri = $secret_part[0]."secret=".$iphone32; #still no good */ $retarr = self::generateQR($iphone_uri); # Let's get a human-readable secret $human_secret0 = str_replace('=', '', $secret); $i = 0; $human_secret = ''; foreach (str_split($human_secret0) as $char) { $human_secret .= $char; ++$i; if ($i == 4) { $human_secret .= ' '; $i = 0; } } $retarr['secret'] = $secret; $retarr['human_secret'] = $human_secret; $retarr['username'] = $this->username; return $retarr; } catch (Exception $e) { return array('status' => false, 'human_error' => 'Unexpected error in makeTOTP', 'error' => $e->getMessage(), 'username' => $this->username, 'provider' => $provider, 'label' => $totp->getLabel(), 'uri' => $uri, 'secret' => $secret); } }
/** * Create a kid from the public that the registry will * use to verify the public key it got configured. * @return string * @throws InvalidAccessException */ public function getKid() { return implode(':', array_slice(str_split(rtrim(Base32::encode(hash('sha256', $this->getPublicKey(true), true)), '='), 4), 0, 12)); }
public function toBase32String() { return Base32::encode($this->digest); }
/** * @return string */ public function getUrl() : string { $options = $this->getOptions(); $options['secret'] = trim(Base32::encode($this->getSecret()), '='); return sprintf('otpauth://%s/%s?%s', $this->getType(), $this->hasLabel() ? $this->getLabel() : '', http_build_query($options)); }