What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Store each TOTP seed as recoverable, encrypted key material—not as a password hash—and restrict which part of your Node.js service can decrypt it. To replace a user’s authenticator, enroll and verify a new seed before revoking the old one. To stop a valid code being replayed, atomically record the accepted time step in shared state. These are separate jobs: protecting the seed, managing its lifecycle, and enforcing one-time use of each valid code.

How do I store TOTP secrets securely?

A TOTP seed is a persistent shared secret: the authenticator and verifier use the same seed to calculate time-based codes. A submitted six-digit code is a temporary output, not the seed itself. RFC 6238 recommends protecting key material in a secure area and limiting access to the processes that need it. NIST SP 800-63B-4 likewise treats authenticator binding and secret protection as security responsibilities.

  • Generate each seed with Node.js’s cryptographically secure random generator or an equivalent approved CSPRNG. NIST specifies that the symmetric key and algorithm should provide at least 112 bits of security strength.
  • Encrypt the seed with authenticated encryption before storing it. Keep the encryption key separate from the database ciphertext, ideally in a key-management service or hardware-backed system with narrowly scoped permissions.
  • Store the nonce or IV, authentication tag, algorithm or format version, and key identifier alongside the ciphertext. These values are needed to decrypt the record safely; they are not substitutes for protecting the key.
  • Limit decryption to the verifier path, keep plaintext exposure brief, and do not log seeds, provisioning URIs, encryption keys, or submitted OTPs.
  • Track lifecycle metadata such as enrollment status and time, revocation status, and the encryption-key version. Avoid storing more sensitive data than the lifecycle and audit process requires.

A database encrypted with a key that every application component can access offers less separation than a narrowly permissioned key service or HSM. The latter adds availability and operational dependencies, so account for those in authentication and recovery design. RFC 6238 identifies tamper-resistant hardware encryption as a stronger storage option.

Encrypt the seed; do not hash it

Password hashing is intentionally one-way. A verifier cannot calculate future TOTP values from a hash, so hashing the seed alone makes normal verification impossible. Encrypt the seed with authenticated encryption instead, and protect the encryption key independently. Encryption does not solve authorization, backups, key rotation, or incident response by itself.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Yubico - YubiKey 5C NFC - Multi-Factor authentication (MFA) Security Key and passkey, Connect via USB-C or NFC, FIDO Certified - Protect Your Online Accounts
  • POWERFUL SECURITY KEY: The YubiKey 5C NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
  • WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C NFC secures 100+ of your favorite accounts, including email, password managers, and more
  • FAST & CONVENIENT LOGIN: Plug in your YubiKey 5C NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
  • MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
  • PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts

Use Node.js authenticated-encryption APIs

Use the current Node.js crypto APIs, such as createCipheriv and createDecipheriv, rather than the deprecated password-based createCipher() and createDecipher() APIs. For example, AES-256-GCM uses a 32-byte key and authenticates the ciphertext; the cited Node.js v26.7.0 documentation specifies a 16-byte default authentication tag for AES-GCM. Generate an unpredictable, unique IV for each encryption. Do not reuse a static IV.

import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';

const ALGORITHM = 'aes-256-gcm';
const IV_BYTES = 12;

export function encryptSeed(seed, key, keyId) {
  if (key.length !== 32) throw new Error('Invalid encryption key length');

  const iv = randomBytes(IV_BYTES);
  const cipher = createCipheriv(ALGORITHM, key, iv);
  // Bind ciphertext to its intended record context where practical.
  cipher.setAAD(Buffer.from(`totp-seed:${keyId}`));

  const ciphertext = Buffer.concat([
    cipher.update(seed, 'utf8'),
    cipher.final(),
  ]);

  return {
    algorithm: ALGORITHM,
    keyId,
    iv: iv.toString('base64'),
    tag: cipher.getAuthTag().toString('base64'),
    ciphertext: ciphertext.toString('base64'),
  };
}

export function decryptSeed(record, key) {
  if (record.algorithm !== ALGORITHM || key.length !== 32) {
    throw new Error('Unsupported seed encryption configuration');
  }

  const decipher = createDecipheriv(
    record.algorithm,
    key,
    Buffer.from(record.iv, 'base64'),
  );
  decipher.setAAD(Buffer.from(`totp-seed:${record.keyId}`));
  decipher.setAuthTag(Buffer.from(record.tag, 'base64'));

  // final() throws if authentication fails; do not use partial plaintext.
  return Buffer.concat([
    decipher.update(Buffer.from(record.ciphertext, 'base64')),
    decipher.final(),
  ]).toString('utf8');
}

This is a minimal pattern, not a complete key-management system: load key through a protected key service rather than embedding it in source code or storing it beside the ciphertext. In production, handle malformed records and decryption or tag-authentication failures as hard errors, without logging secrets or continuing with partial plaintext. Use the documentation for the Node.js version you deploy.

Rank #2
Thetis Nano-C for Business - USB C FIDO2 Security Key L1 MFA & Passkey Access for School ERP, Employee Online Account, Compatible with Coinbase Google Workspace Apple ID Window Salesfore - 2 Pack
  • FIDO2 & Passkey Ready: Business-ready and FIDO2 L1 certified. This key is supported by major management suites and is ideal for both individual and enterprise deployment. Works seamlessly with Gmail, Facebook, GitHub, Dropbox, Coinbase, and more.
  • Dedicated Manager App: Use the Thetis Manager App for the initial hardware PIN setup. Setting the PIN on the device first ensures a smooth registration process. Once the PIN is configured, you can begin registering the key across your favorite FIDO2-compatible online services.
  • USB TYPE C Connectivity & DONGLE Design: Designed for PCs, Macs, laptops, iPhones, and Android devices that utilize a USB-C port. Plug and stay, or carry it on a keychain. (Item Size: 0.73 x 0.60 x 0.30 inches)
  • Enhanced MFA (FIDO2 & TOTP/HOTP): Strengthen your security with flexible options. Use the Manager App to access TOTP/HOTP features for accounts that do not yet support FIDO2.
  • Check FIDO2 compatibility before purchase - Known limitations: ID Austria is not supported (requires FIDO2 Level 2). Windows Hello login only works with Windows Enterprise editions that support Entra ID. NFC functionality is not supported.

How do I enroll and rotate a TOTP secret?

Authenticator-seed rotation means replacing the user’s shared secret. It is not the same as rotating the server’s encryption key. For device replacement, NIST’s guidance is to bind the new authenticator and invalidate the one that will no longer be used.

  1. Start an authenticated enrollment flow. Require the user to authenticate under your policy, then generate a new independent seed. Keep it pending rather than treating generation as activation.
  2. Show or provision the seed through that flow only. A QR code or provisioning URI contains the seed and must be protected like the seed itself. Do not send it to logs, analytics, or an untrusted client channel.
  3. Require proof of possession. Ask the authenticator for a code and verify it against the pending seed before activating the new binding. Discard or expire an unconfirmed pending seed according to your enrollment policy.
  4. Activate and revoke deliberately. Once the new authenticator is verified, update lifecycle state so the old seed is no longer accepted. If you allow an overlap period for usability, make it explicit, brief, and policy-controlled: the old secret remains valid during that period.
  5. Handle recovery as a credential change. Lost-device recovery, deactivation, suspected compromise, and administrative reset paths should revoke the affected seed and require fresh binding. Do not let a recovery or backup-code flow silently keep a known-compromised seed active.

The cited NIST guidance does not establish a universal calendar-based interval for replacing TOTP seeds. Set replacement triggers around events such as device changes, suspected compromise, or recovery rather than inventing a periodic interval without a policy basis.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Thetis FIDO2 Security Key (USB-A, 2-Pack) - Hardware MFA & Passkey Access for Business, School ERP & Employee Accounts | Compatible with Windows, Google Workspace, Apple ID, Coinbase, Salesforce
  • FIDO2 & Passkey Ready: Business-ready and FIDO2 L1 certified. This key is supported by major management suites and is ideal for both individual and enterprise deployment. Works seamlessly with Gmail, Facebook, GitHub, Dropbox, Coinbase, and more.
  • Universal Connectivity (USB-A ): Features a built-in USB-A connector—simply unfold the key and plug it into your compatible PC or laptop for seamless authentication on the go.
  • Dedicated Manager App: Use the Thetis Manager App for the initial hardware PIN setup. Setting the PIN on the device first ensures a smooth registration process. Once the PIN is configured, you can begin registering the key across your favorite FIDO2-compatible online services.
  • Ultra-Durable & Portable: Featuring a rotating metal cover, this key is water, crush, and tamper-resistant. It fits easily on a keychain and requires no batteries or network connectivity.
  • Check FIDO2 compatibility before purchase - Known limitations: ID Austria is not supported (requires FIDO2 Level 2). Windows Hello login only works with Windows Enterprise editions that support Entra ID, and NFC is NOT supported.

How do I prevent a TOTP code from being reused?

TOTP verification commonly permits a bounded time-step window to accommodate clock drift and the time needed to enter or transmit a code. A code that verifies successfully must not be accepted again while it remains valid. NIST SP 800-63B-4 and OWASP ASVS 5.0 require one-time acceptance while valid; NIST also requires a defined lifetime and rate limiting for failed attempts.

Use a bounded window and synchronized clocks

Choose the accepted time steps based on measured clock drift and realistic user-entry or network delay. Do not widen the window arbitrarily: each additional accepted step increases the period in which a code could be accepted. Synchronize verifier clocks, monitor drift, and rate-limit failed attempts per account and other relevant dimensions. Return generic authentication failures so responses do not reveal which part of verification failed.

Rank #4
Thetis Pro For Business - FIDO2 Security Key L1 MFA & NFC Passkey Access For School ERP, Employee Online Account, Compatible with Coinbase Google Workspace Apple ID Window Salesforce,Dual USB A +USB C
  • FIDO2 & Passkey Ready: Business-ready and FIDO2 L1 certified. This key is supported by major management suites and is ideal for both individual and enterprise deployment. Works seamlessly with Gmail, Facebook, GitHub, Dropbox, Coinbase, and more.
  • Dedicated Manager App: Use the Thetis Manager App for the initial hardware PIN setup. Setting the PIN on the device first ensures a smooth registration process. Once the PIN is configured, you can begin registering the key across your favorite FIDO2-compatible online services.
  • Universal Connectivity (USB-C, USB-A, & NFC): Designed for PCs, Macs, iPhones, and Android. For mobile use, simply unfold the key, align it with your phone’s NFC antenna, and hold for a few seconds to authenticate.
  • Enhanced MFA (FIDO2 & TOTP/HOTP): Strengthen your security with flexible options. Use the Manager App to access TOTP/HOTP features for accounts that do not yet support FIDO2.
  • Check FIDO2 compatibility before purchase - Known limitations: ID Austria is not supported (requires FIDO2 Level 2). Windows Hello login only works with Windows Enterprise editions that support Entra ID. NFC is supported only through mobile authentication, Not MacOS/windows.

Consume the accepted step atomically

After a code matches a candidate time step, update shared replay state before completing authentication. A common design records the greatest accepted time step for each active seed and accepts a match only if it is greater than the stored value. This prevents a previously accepted step from being accepted again and also rejects older steps that arrive late. Choose state semantics that fit your window and concurrent request behavior.

  • Make verification and the replay-state update one atomic conditional operation, such as a database transaction or compare-and-set.
  • Keep replay state in a shared database or cache with atomic semantics; process-local memory is insufficient when requests can reach different Node.js instances.
  • If the conditional update loses a race, reject that request even if its code matched cryptographically.
  • Test simultaneous submissions across instances, retries, clock-window boundaries, and failed state-store operations. Fail closed if replay state cannot be safely updated.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How is encryption-key rotation different?

Encryption-key rotation is a server-side data-protection operation: it changes the key used to protect stored seeds without changing the user’s authenticator. Keep a key identifier or version with each encrypted record so the verifier can select the correct key.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Thetis Nano-A FIDO2 Security Key Hardware Passkey Device with USB Type A, TOTP/HOTP, FIDO2.0 Two Factor Authentication 2FA MFA, Works with Windows/mac/iOS/Android/Linux/Gmail/Facebook/GitHub/Coinbase
  • Ultra-Compact FIDO2 Security Key - Plug-and-stay or carry on a keychain. This USB-A hardware security key offers portable, always-on protection for desktop and mobile use. (Item Size: 0.75 X 0.74 IN x 0.25 IN)
  • USB-A Hardware Key for All Devices - Works with USB-A ports on PC, Mac, Android, and other laptop/notebook device. Enables secure, cross-platform login with FIDO2.0 passkey support.
  • FIDO Certified Security Key - Meets FIDO and FIDO2 standards. Works with Google, Microsoft, GitHub, Dropbox, and more. Please check service compatibility before purchase.
  • Passwordless Login with Passkey - Supports passkey login via WebAuthn and CTAP2. Enjoy password-free sign-ins where supported. Not all websites or services currently support passkeys.
  • Advanced Multi-Factor Authentication - Offers 200 FIDO2 passkey slots and 50 OATH-TOTP slots. Strong, flexible 2FA/MFA support across various apps and authentication platforms.
  1. Introduce the new key version. Make it available to the narrowly authorized encryption/decryption path while retaining the old version for records not yet migrated.
  2. Migrate records safely. Decrypt each seed with its recorded old key and re-encrypt it under the current key, or use envelope encryption and rotate the wrapping key. Verify the new record before marking migration complete.
  3. Retire old key versions only when safe. Keep them only as long as migration, backup retention, and recovery requirements call for. Test restoration and migration before destroying access to an old version.
  4. Respond to exposure as an incident. If an encryption key is compromised, determine which seeds it could expose and follow a revocation and re-enrollment plan appropriate to that scope.

This migration pattern follows from encrypted persistent seed storage and Node.js encryption primitives; it is not a step-by-step rotation procedure mandated by RFC 6238. Preserve an independently protected recovery path: losing the encryption key can make every seed encrypted under it unusable.

What is different about other OTPs?

This guidance is for TOTP, where a persistent seed is used with time steps. HOTP is counter-based, so counter synchronization and advancement are part of its lifecycle. Email or SMS verification codes are usually generated and delivered per challenge rather than derived from a long-lived authenticator seed; their storage, expiration, delivery, and replay controls need a separate design. Do not assume that TOTP seed storage rules alone cover those systems.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.