├── LICENSE ├── README.md ├── composer.json ├── src └── otp.class.php └── test ├── newotp.php └── verifyotp.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mohammad Sakib 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP OTP Without Database 2 | ## What is it? 3 | This is a simple script written in php to verify One Time Password **(OTP)** without any database. You can read the [blog post here](https://blog.anam.co/otp-verification-without-using-a-database/) to understand the technique and motivation. 4 | 5 | ## How to install 6 | ``` 7 | git clone https://github.com/moh4mmad/php-otp-without-database.git 8 | ``` 9 | or 10 | ``` 11 | composer require moh4mmad/php-otp-without-database 12 | ``` 13 | ## Usage 14 | You need additional tool to send SMS. This module only takes care of the verification part. 15 | ## Verification process 16 | OTP verification is done in the following steps: 17 | - A hash is created with the phone number/email address and then sent to the user. 18 | - The user also receives the OTP via SMS, email or any other method. 19 | - The user sends back the hash, OTP and phone/email used in the first request. 20 | - The server verifies the information and returns true if they match. 21 | 22 | ## Generating OTP Hash 23 | ``` 24 | $otp = new Sakib\OTP; 25 | $email = "test@abc.com"; 26 | $code = $otp->generateRandomString(6); 27 | $hash = $otp->CreateOTP($email, $code); 28 | ``` 29 | You can then send this hash to the user as response. 30 | ``` 31 | CreateOTP($email, $otp, $key = "verysecret", $min = 5, $algo = "sha256"); 32 | ``` 33 | ## Verifying OTP hash 34 | The user should get the hash from the HTTP request and should get the real OTP via SMS or email. 35 | Then when the user sends back the information, they can be verified with the following code: 36 | ``` 37 | VerifyTOP($email, $otp, $hash, $key="verysecret", $algo = "sha256"); 38 | ``` 39 | This method returns a Boolean. If the verification is successful, it will return true. 40 | 41 | ## Issues 42 | If you come across any issues please report them [here](https://github.com/moh4mmad/php-otp-without-database/issues) 43 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moh4mmad/php-otp-without-database", 3 | "description": "OTP verification using cryptography without database", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Sakib", 9 | "email": "sakib@sakib.info" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": { 14 | "Sakib\\": "src/" 15 | } 16 | }, 17 | "version": "1.0.0", 18 | "require": {} 19 | } 20 | -------------------------------------------------------------------------------- /src/otp.class.php: -------------------------------------------------------------------------------- 1 | $hashdata[1] ) { 47 | return false; 48 | } 49 | 50 | // Calculate new hash with the same key and the same algorithm 51 | $data = $email . $otp . $hashdata[1]; 52 | $newHash = hash_hmac($algo, $data, $key); 53 | 54 | // Match the hashes 55 | if ($newHash == $hashdata[0]) { 56 | return true; 57 | } 58 | } else { 59 | return false; 60 | } 61 | } 62 | 63 | /** 64 | * Generate Random String 65 | * 66 | * @param integer $length 67 | * @return string 68 | */ 69 | public function generateRandomString($length = 6) 70 | { 71 | $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 72 | $charactersLength = strlen($characters); 73 | $randomString = ''; 74 | 75 | for ($i = 0; $i < $length; $i++) { 76 | $randomString .= $characters[rand(0, $charactersLength - 1)]; 77 | } 78 | 79 | return $randomString; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /test/newotp.php: -------------------------------------------------------------------------------- 1 | generateRandomString(6); 9 | $email = $_POST['email']; 10 | $hash = $otp->CreateOTP($email,$code); 11 | $_SESSION['email'] = $email; 12 | $_SESSION['hash'] = $hash; 13 | header("Location: verifyotp.php"); 14 | } 15 | ?> 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 |