
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
@otplib/plugin-base32-scure
Advanced tools
Base32 encoding/decoding plugin for otplib using the @scure/base library.
npm install @otplib/plugin-base32-scure
pnpm add @otplib/plugin-base32-scure
yarn add @otplib/plugin-base32-scure
This plugin provides Base32 encoding and decoding using @scure/base, a cryptographic library which is audited and has comprehensive TypeScript support.
import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();
// Generate a secret
const secret = generateSecret({ crypto, base32 });
// Generate a token
const token = await generate({
secret,
crypto,
base32,
});
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
const base32 = new ScureBase32Plugin();
// Encode binary data to Base32
const data = new Uint8Array([1, 2, 3, 4, 5]);
const encoded = base32.encode(data, { padding: true });
// Output: "AEBAGBAF"
// Decode Base32 string to binary
const decoded = base32.decode("AEBAGBAF");
// Output: Uint8Array [1, 2, 3, 4, 5]
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
const base32 = new ScureBase32Plugin();
// Encode without padding
const encoded = base32.encode(data, { padding: false });
// Output: "AEBAGBAF"
// Decode handles both padded and unpadded strings
const decoded1 = base32.decode("AEBAGBAF===="); // With padding
const decoded2 = base32.decode("AEBAGBAF"); // Without padding
Use this plugin when:
Works in all environments:
import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();
const secret = generateSecret({ crypto, base32 });
console.log(secret); // Base32-encoded secret
const token = await generate({ secret, crypto, base32 });
console.log(token); // 6-digit token
import { generateSecret, generate } from "otplib";
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";
const base32 = new ScureBase32Plugin();
const crypto = new WebCryptoPlugin();
const secret = await generateSecret({ crypto, base32 });
const token = await generate({ secret, crypto, base32 });
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { NodeCryptoPlugin } from "@otplib/plugin-crypto-node";
const base32 = new ScureBase32Plugin();
const crypto = new NodeCryptoPlugin();
// Generate random secret
const secretBytes = crypto.randomBytes(20);
const secret = base32.encode(secretBytes, { padding: false });
console.log(secret); // Base32 secret for TOTP
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { WebCryptoPlugin } from "@otplib/plugin-crypto-web";
export default {
async fetch(request) {
const base32 = new ScureBase32Plugin();
const crypto = new WebCryptoPlugin();
// Generate secret
const secretBytes = await crypto.randomBytes(20);
const secret = base32.encode(secretBytes, { padding: false });
return new Response(JSON.stringify({ secret }));
},
};
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
const base32 = new ScureBase32Plugin();
function validateAndDecode(input: string): Uint8Array | null {
try {
// @scure/base validates:
// - Character set (A-Z, 2-7)
// - Length (must be multiple of 8 with padding, or correct without)
// - Padding (if present, must be correct)
return base32.decode(input);
} catch (error) {
console.error("Invalid Base32:", error.message);
return null;
}
}
const valid = validateAndDecode("JBSWY3DPEHPK3PXP");
const invalid = validateAndDecode("invalid@base32!");
import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
import { base32 as scureBase32 } from "@scure/base";
const plugin = new ScureBase32Plugin();
// Use plugin's convenience methods
const encoded = plugin.encode(data);
// Or use @scure/base directly for advanced options
const encoded = scureBase32.encode(data, { padding: false });
{
"dependencies": {
"@scure/base": "^1.1.0"
}
}
@scure/base - Audited encoding/decoding library@otplib/core - Core types and interfaces@otplib/plugin-crypto-node - Node.js crypto plugin@otplib/plugin-crypto-web - Web Crypto API pluginFull documentation available at otplib.yeojz.dev:
MIT © 2026 Gerald Yeo
FAQs
Base32 plugin for otplib using @scure/base
The npm package @otplib/plugin-base32-scure receives a total of 0 weekly downloads. As such, @otplib/plugin-base32-scure popularity was classified as not popular.
We found that @otplib/plugin-base32-scure demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.