Featured image of post HOTP / TOTP test

HOTP / TOTP test

Source: GitHub / [OneTimePassword] 一次性密碼演算法:簡介HOTP、TOTP和Google Authenticator | 全端開發人員天梯

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>OTP Demo</title>
</head>

<body>
    <h1>Options</h1>
    <p>
        <label for="secret">Secret Key</label>
        <input name="secret" id="secret" size="64" />
        <button id="generateSecret">Generate Secret</button>
    </p>

    <h2>HOTP</h2>
    <p>
        <label for="counter">Counter (Message)</label>
        <input name="counter" id="counter" size="64" value="" placeholder="any number...">
        <button id="generateHoptPassword">Generate HOPT password</button>
    </p>
    <p>
        HOPT Password:<input id="hotpPassword" />
    </p>
    <p>
        <button id="verifyHotp">Verify</button> Result: <span id="verifyHotpResult"></span>
    </p>

    <h2>TOTP</h2>
    <p>
        <label for="tc">TC</label>
        <input name="tc" id="tc" value="30">
    </p>
    <p>
        TOTP Password:<input id="totpPassword" />
    </p>
    <p>
        <span id="timeLeft"></span> sec left.
    </p>
    <p>
        <button id="verifyTotp">Verify</button> Result: <span id="verifyTotpResult"></span>
    </p>

    <h2>Google Authenticator</h2>
    <p>
        <label for="user">User</label>
        <input name="user" id="user" value="test user name">
    </p>
    <p>
        <label for="service">Service Name</label>
        <input name="service" id="service" value="Awesome OTP">
    </p>
    <p>
        <img id="qrcode" />
    </p>

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/otplib@^6.0.0/otplib-browser.js"></script>
    <script>
        $(document).ready(function () {
            var qrCodeApi = 'https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl=';
            function generateHoptPassword() {
                var token = otplib.hotp.generate($('#secret').val(), $('#counter').val());
                $('#hotpPassword').val(token);
            }

            function generateTotpPassword() {
                otplib.authenticator.options = {
                    step: parseInt($('#tc').val())
                };
                var token = otplib.authenticator.generate($('#secret').val());
                $('#totpPassword').val(token);

                var authParam = otplib.authenticator.keyuri(
                    encodeURIComponent($('#user').val()), 
                    encodeURIComponent($('#service').val()), 
                    $('#secret').val());
                var url = qrCodeApi + encodeURIComponent(authParam);
                $('#qrcode').attr('src', url);
            }

            function checkTimeLeft() {
                var tc = parseInt($('#tc').val());
                var epoch = Math.floor(new Date().getTime() / 1000);
                var count = epoch % tc;
                var timeLeft = tc - count;
                $('#timeLeft').text(timeLeft);
                if (timeLeft === tc) {
                    generateTotpPassword();
                }
            }

            var refreshTotpHandle = setInterval(checkTimeLeft, 1000);
            generateTotpPassword();
            checkTimeLeft();

            $('#generateSecret').click(function () {
                var secret = otplib.authenticator.generateSecret();
                $('#secret').val(secret);
                generateHoptPassword();
                generateTotpPassword();
            });

            $('#generateHoptPassword').click(function () {
                generateHoptPassword();
            });

            $('#verifyHotp').click(function () {
                var result = otplib.hotp.verify({
                    token: $('#hotpPassword').val(),
                    secret: $('#secret').val(),
                    counter: $('#counter').val()
                });

                if (result) {
                    $('#verifyHotpResult').text('pass');
                } else {
                    $('#verifyHotpResult').text('fail');
                }
            });

            $('#verifyTotp').click(function () {
                var result = otplib.authenticator.verify({
                    secret: $('#secret').val(),
                    token: $('#totpPassword').val()
                });


                if (result) {
                    $('#verifyTotpResult').text('pass');
                } else {
                    $('#verifyTotpResult').text('fail');
                }
            })

            $('#generateSecret').trigger('click');
        });
    </script>
</body>

</html>