| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- <?php
- session_start(); // using it as storage temporary
- require_once __DIR__ . '/../vendor/autoload.php';
- use Otp\Otp;
- use Otp\GoogleAuthenticator;
- use ParagonIE\ConstantTime\Encoding;
- // Getting a secret, either by generating or from storage
- // DON'T use sessions as storage for this in production!!!
- $secret = 0;
- if (isset($_SESSION['otpsecret'])) {
- $secret = $_SESSION['otpsecret'];
- }
- if (strlen($secret) != 16) {
- $secret = GoogleAuthenticator::generateRandom();
- $_SESSION['otpsecret'] = $secret;
- }
- // The secret is now an easy stored Base32 string.
- // To use it in totp though we need to decode it into the original
- $otp = new Otp();
- $currentTotp = $otp->totp(Encoding::base32DecodeUpper($secret));
- $qrCode = GoogleAuthenticator::getQrCodeUrl('totp', 'otpsample@cr', $secret);
- $keyUri = GoogleAuthenticator::getKeyUri('totp', 'otpsample@cr', $secret);
- ?><html>
- <head>
- <title>One Time Passwords Example</title>
- </head>
- <body>
- <h1>One Time Passwords Example</h1>
- Secret is <?php echo $secret; ?>. This is saved with the users credentials.
- <br />
- <br />
- <hr />
- QR Code for totp:<br />
- <img src="<?php echo $qrCode; ?>" />
- <br />
- This QR Code contains the Key URI: <?php echo $keyUri; ?>
- <br />
- <hr />
- Current totp would be <?php echo $currentTotp; ?><br />
- <br />
- <hr />
- Because of timedrift, you could technically enter a code before or after it
- would actually be used. This form uses the checkTotp function. To test this,
- open this page, wait until the key changes once or twice (not more) on your
- Google Authenticator, then hit submit. Even though the key is "wrong" because of
- small time differences, you can still use it.
- <form action="" method="post">
- <input type="text" name="otpkey" value="<?php echo $currentTotp; ?>" /><br />
- <input type="submit">
- </form>
- <br />
- Output:<br />
- <br />
- <?php
- if (isset($_POST['otpkey'])) {
- // Sanitizing, this should take care of it
- $key = preg_replace('/[^0-9]/', '', $_POST['otpkey']);
-
- // Standard is 6 for keys, but can be changed with setDigits on $otp
- if (strlen($key) == 6) {
- // Remember that the secret is a base32 string that needs decoding
- // to use it here!
- if ($otp->checkTotp(Encoding::base32DecodeUpper($secret), $key)) {
- echo 'Key correct!';
- // Add here something that makes note of this key and will not allow
- // the use of it, for this user for the next 2 minutes. This way you
- // prevent a replay attack. Otherwise your OTP is missing one of the
- // key features it can bring in security to your application!
- } else {
- echo 'Wrong key!';
- }
-
- } else {
- echo 'Key not the correct size';
- }
- }
- ?>
- </body>
- </html>
|