Search

Authentification


 


totp-simulator.html HTML5 + Web Crypto API
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: sans-serif; display: flex; justify-content: center; }
        .card { background: white; padding: 2rem; border-radius: 12px; width: 350px; }
        .code { font-size: 3rem; font-weight: bold; text-align: center; }
        #progress-bar { width: 100%; height: 8px; background: #1a73e8; }
    </style>
</head>
<body>

<div class="card">
    <h2>Mon Authenticator</h2>
    <input type="text" id="secretInput" value="JBSWY3DPEHPK3PXP">
    <div id="totp-display" class="code">------</div>
    <div id="progress-bar"></div>
</div>

<script>
    // Algorithme TOTP conforme RFC 6238
    const TOTP = {
        base32ToBuf(str) {
            const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
            let bits = "";
            for (let i = 0; i < str.length; i++) {
                const val = alphabet.indexOf(str[i].toUpperCase());
                if (val === -1) continue;
                bits += val.toString(2).padStart(5, '0');
            }
            const bytes = [];
            for (let i = 0; i + 8 <= bits.length; i += 8) {
                bytes.push(parseInt(bits.substring(i, i + 8), 2));
            }
            return new Uint8Array(bytes);
        },

        async generate(secretBase32) {
            const keyBuf = this.base32ToBuf(secretBase32);
            const epoch = Math.floor(Date.now() / 1000);
            const counter = Math.floor(epoch / 30);

            const counterBuf = new ArrayBuffer(8);
            const view = new DataView(counterBuf);
            view.setUint32(4, counter);

            const cryptoKey = await crypto.subtle.importKey(
                "raw", keyBuf, { name: "HMAC", hash: "SHA-1" }, false, ["sign"]
            );

            const hmac = await crypto.subtle.sign("HMAC", cryptoKey, counterBuf);
            const res = new Uint8Array(hmac);
            const offset = res[res.length - 1] & 0xf;
            const code = ((res[offset] & 0x7f) << 24 | (res[offset + 1] & 0xff) << 16 | 
                          (res[offset + 2] & 0xff) << 8 | (res[offset + 3] & 0xff)) % 1000000;

            return code.toString().padStart(6, '0');
        }
    };
</script>
</body>
</html>

Ces posts pourraient vous intéresser: