Php integrated dynamic password authentication, php Dynamic Password

Source: Internet
Author: User
Tags php framework sha1 hash

Php integrated dynamic password authentication, php Dynamic Password

Most systems currently use static passwords for identity authentication and logon. However, because static passwords are easy to steal, their security cannot meet security requirements.

Dynamic passwords use one password at a time and have expired passwords to prevent security problems caused by password theft.
Dynamic passwords include HOTP (Event-based dynamic passwords, RFC4226), TOTP (time-based dynamic passwords, RFC6238), and OCRA (challenge-response dynamic passwords, RFC6287.

This article introduces the dynamic password authentication solution Integrated with TOTP. The PHP framework uses Thinkphp3.2.3 and the dynamic password generator uses google authtication.

1. Add an oath algorithm class for the Thinkphp framework

Oath algorithm encapsulation class oath. php code is as follows:

<?PHP/** * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see 

Because the seed key in google's dynamic password algorithm uses base32 encoding, The base32 algorithm is required. The content of base32.php is as follows:

<?php//namespace Base32;/** * Base32 encoder and decoder * * Last update: 2012-06-20 * * RFC 4648 compliant * @link http://www.ietf.org/rfc/rfc4648.txt * * Some groundwork based on this class * https://github.com/NTICompass/PHP-Base32 * * @author Christian Riesen <chris.riesen@gmail.com> * @link http://christianriesen.com * @license MIT License see LICENSE file */class Base32{ /**  * Alphabet for encoding and decoding base32  *  * @var array  */ private static $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='; /**  * Creates an array from a binary string into a given chunk size  *  * @param string $binaryString String to chunk  * @param integer $bits Number of bits per chunk  * @return array  */ private static function chunk($binaryString, $bits) {  $binaryString = chunk_split($binaryString, $bits, ' ');  if (substr($binaryString, (strlen($binaryString)) - 1) == ' ') {   $binaryString = substr($binaryString, 0, strlen($binaryString)-1);  }  return explode(' ', $binaryString); } /**  * Encodes into base32  *  * @param string $string Clear text string  * @return string Base32 encoded string  */ public static function encode($string) {  if (strlen($string) == 0) {   // Gives an empty string   return '';  }  // Convert string to binary  $binaryString = '';  foreach (str_split($string) as $s) {   // Return each character as an 8-bit binary string   $binaryString .= sprintf('%08b', ord($s));  }  // Break into 5-bit chunks, then break that into an array  $binaryArray = self::chunk($binaryString, 5);  // Pad array to be divisible by 8  while (count($binaryArray) % 8 !== 0) {   $binaryArray[] = null;  }  $base32String = '';  // Encode in base32  foreach ($binaryArray as $bin) {   $char = 32;   if (!is_null($bin)) {    // Pad the binary strings    $bin = str_pad($bin, 5, 0, STR_PAD_RIGHT);    $char = bindec($bin);   }   // Base32 character   $base32String .= self::$alphabet[$char];  }  return $base32String; } /**  * Decodes base32  *  * @param string $base32String Base32 encoded string  * @return string Clear text string  */ public static function decode($base32String) {  // Only work in upper cases  $base32String = strtoupper($base32String);  // Remove anything that is not base32 alphabet  $pattern = '/[^A-Z2-7]/';  $base32String = preg_replace($pattern, '', $base32String);  if (strlen($base32String) == 0) {   // Gives an empty string   return '';  }  $base32Array = str_split($base32String);  $string = '';  foreach ($base32Array as $str) {   $char = strpos(self::$alphabet, $str);   // Ignore the padding character   if ($char !== 32) {    $string .= sprintf('%05b', $char);   }  }  while (strlen($string) %8 !== 0) {   $string = substr($string, 0, strlen($string)-1);  }  $binaryArray = self::chunk($string, 8);  $realString = '';  foreach ($binaryArray as $bin) {   // Pad each value to 8 bits   $bin = str_pad($bin, 8, 0, STR_PAD_RIGHT);   // Convert binary strings to ASCII   $realString .= chr(bindec($bin));  }  return $realString; }}?>

Put the two files in the Thinkphp Framework's ThinkPHP \ Library \ Vendor \ oath directory, which is created by yourself.

2. Add database fields

Add the following fields to the user table:
Auth_type (0-static password, 1-dynamic password)
Seed)
Temp_seed (temporary seed key)
Last_logintime (last logon success time)
Last_otp (password used last time)
Auth_type indicates the authentication method used by the user. seed is the seed key of the user, and temp_seed is a seed key temporarily saved before the user is activated. If the user successfully activated dynamic password authentication, this field is entered in the seed field. Last_logintime and last_otp are the time when the last authentication was successful and dynamic passwords. They are used to avoid repeated use of the same password.

3. Code Integration

1) activate the Dynamic Password

Add the authentication method on the password change page of the original system, for example:

If you select the dynamic password method, a QR code is generated and displayed on the page for you to activate the dynamic password. To be compatible with google authtication, the QR code is in the same format as google. For more information about how to generate a QR code, see Thinkphp3.2.3 integrate phpqrcode to generate a QR code with a logo.
The code for generating the key QR code is as follows:

Public function qrcode () {Vendor ('oss. base32'); $ base32 = new \ base32 (); $ rand = random (16); // generate random seeds $ rand = $ Base32-> encode ($ rand ); $ rand = str_replace ('=', '', $ rand); // remove the filled '=' $ errorCorrectionLevel = intval (3 ); // fault tolerance level $ matrixPointSize = intval (8); // generate the image size // generate the QR code image Vendor ('phpqrcode. phpqrcode '); $ object = new \ QRcode (); $ text = sprintf ("otpauth: // totp/% s? Secret = % s ", $ user, $ rand); $ object-> png ($ text, false, $ errorCorrectionLevel, $ matrixPointSize, 2 ); generated seed $ rand saved to the database's temp_seed field}

Random is a random string generation function. $ Rand = str_replace ('=', '', $ rand) is because the base32 decoding algorithm in the Google mobile token does not contain the '=' sign.

The code for verifying a user's dynamic password is as follows:

Read temp_seedVendor ('oss. oath '); $ object = new \ Google2FA (); if ($ object-> verify_key ($ temp_seed, $ otp) {Verification Successful. The database is updated to temp_seed, auth_type is 1, last_otp is otp}

2) Dynamic Password Logon

User Dynamic Password Logon verification code:

Read the auth_type, seed, last_otp fields from the database.

If ($ auth_type = 1) {// dynamic password // prevent repeated authentication if ($ lat_otp = $ otp) {Dynamic Password reuse return} Vendor ('oath. oath '); $ object = new \ Google2FA (); if (! $ Object-> verify_key ($ seed, $ otp) {incorrect dynamic password} else {logon successful. Set last_otp to $ otp and last_logintime to time ()}}

4. test and verification

Download google authtication and log on to the system with the static password to go to the password modification page.
Open google authtication and scan the QR code. A dynamic password is displayed.

Save the content and activate the dynamic password!
Then you can log on to the system with a dynamic password!

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.