Install @better-auth/utils
mainInstall the package using pnpm to access common authentication utilities like hashing, encryption, and OTP generation.
pnpm add @better-auth/utilsrepository·main·Indexed 42 days ago
https://github.com/better-auth/utilsA TypeScript library providing unified, high-level APIs for common authentication-related cryptographic tasks. It leverages Web Crypto APIs for compatibility across Node.js and web environments, offering utilities for hashing (SHA, scrypt), HMAC, RSA/ECDSA asymmetric encryption, OTP generation (HOTP and TOTP), and various encoding formats including Base32, Base64, and Hexadecimal. Version 0.5.0.
Install the package using pnpm to access common authentication utilities like hashing, encryption, and OTP generation.
pnpm add @better-auth/utilsUse base64 for standard encoding or base64Url for URL-safe encoding.
base64.encode(data, { padding, url }) and base64.decode(encodedData).base64Url.encode(data) for a URL-safe alternative.import { base64 } from "@better-auth/utils/base64";
import { base64Url } from "@better-auth/utils/base64";
// Standard
const encoded = base64.encode("Data", { url: true, padding: false });
const decoded = await base64.decode(encoded);
// URL Safe
const urlSafeEncoded = base64Url.encode("Data");The HMAC utility allows you to securely hash data using a secret key.
createHMAC(algorithm, encoding) where algorithm is SHA-256, SHA-384, or SHA-512 and encoding can be none, hex, base64, base64url, or base64urlnopad.hmac.importKey(secretKey) to convert a string, buffer, or typed array into a CryptoKey.hmac.sign(key, data) or pass a raw secret string directly to hmac.sign(secret, { data: '...' }).hmac.verify(key, data, signature) to check if a signature is valid.import { createHMAC } from './hmac';
const hmac = createHMAC("SHA-256", "hex");
const secretKey = "my-secret-key";
// Using imported key
const key = await hmac.importKey(secretKey);
const signature = await hmac.sign(key, "text to sign");
const isValid = await hmac.verify(key, "text to sign", signature);
// Direct signing with raw string
const signature2 = await hmac.sign("secret-key", {
data: "text"
});The OTP utility supports both HOTP (RFC 4226) and TOTP (RFC 6238) standards.
createOTP(secret, options).hotp(counter).createOTP(secret, options).totp()..verify(otp, { window }) to check a code. The window option allows for clock drift compensation..url(issuer, account) to generate a provisioning URL for apps like Google Authenticator.import { createOTP } from "@better-auth/utils/otp";
const secret = "my-super-secret-key";
// HOTP
const hotp = createOTP(secret, { digits: 6 }).hotp(1234);
// TOTP
const totpInstance = createOTP(secret, { digits: 6, period: 30 });
const otp = totpInstance.totp();
const isValid = totpInstance.verify(otp, { window: 60 });
// Authenticator URL
const qrCodeUrl = createOTP(secret).url("my-app", "user@email.com");ECDSA utilities allow for elliptic curve cryptography operations.
ecdsa.generateKeyPair(curve) where curves are P-256, P-384, or P-521.ecdsa.exportKey(key, format) (e.g., pkcs8, spki) and ecdsa.importPrivateKey(key, curve) / ecdsa.importPublicKey(key, curve).ecdsa.sign(privateKey, data, hash) (default hash: SHA-256).ecdsa.verify(publicKey, { signature, data, hash }).import { ecdsa } from "@better-auth/utils/ecdsa";
// Key Pair Generation
const { privateKey, publicKey } = await ecdsa.generateKeyPair("P-256");
// Signing
const signature = await ecdsa.sign(privateKey, "Message to sign", "SHA-256");
// Verifying
const isValid = await ecdsa.verify(publicKey, {
signature,
data: "Message to verify",
hash: "SHA-256",
});Use hex to convert between strings/buffers and hexadecimal representations.
hex.encode(data).hex.decode(encodedData).hex.toBytes(hexString) converts a hex string into a Uint8Array. This is recommended when the hex represents raw binary data (like signatures) rather than UTF-8 text.import { hex } from "@better-auth/utils/hex";
const encoded = hex.encode("Data");
const decoded = hex.decode(encoded);
const bytes = hex.toBytes("48656c6c6f"); // Uint8Array([72, 101, 108, 108, 111])Create a cryptographically secure random string generator by specifying a charset. You can then generate strings of a specific length or override the charset during generation.
import { createRandomStringGenerator } from "@better-auth/utils/random"
// 1. Create generator with specific charset
export const generateRandomString = createRandomStringGenerator("A-Z", "0-9", "a-z", "-_")
// 2. Generate string of length 32
const randomString = generateRandomString(32)
// 3. Override charset for a specific call
const randomString2 = generateRandomString(32, "A-Z", "0-9")Use createHash to generate digests using the SHA family of hash functions. You can specify the encoding for the output (e.g., hex or base64).
import { createHash } from "@better-auth/utils/hash"
const hashBuffer = await createHash("SHA-256").digest("text");
const hashInHex = await createHash("SHA-256", "hex").digest("text");
const hashInBase64 = await createHash("SHA-256", "base64").digest("text");RSA utilities provide high-level methods for asymmetric cryptography.
rsa.generateKeyPair(modulusLength, hashAlgorithm) (default: 2048 bits, SHA-256).rsa.exportKey(key, format) (e.g., jwk, spki) and rsa.importKey(key, usage) (e.g., encrypt, decrypt, sign, verify).rsa.encrypt(publicKey, data) and rsa.decrypt(privateKey, encryptedData).rsa.sign(privateKey, data) and rsa.verify(publicKey, { signature, data }).import { rsa } from "@better-auth/utils/rsa";
// Key Pair Generation
const keyPair = await rsa.generateKeyPair(2048, "SHA-256");
const { publicKey, privateKey } = keyPair;
// Encryption/Decryption
const encryptedData = await rsa.encrypt(publicKey, "Sensitive data");
const decryptedData = await rsa.decrypt(privateKey, encryptedData);
// Signing/Verification
const signature = await rsa.sign(privateKey, "Message to sign");
const isValid = await rsa.verify(publicKey, {
signature,
data: "Message to sign",
});The binary utility uses TextEncoder and TextDecoder to convert strings to Uint8Array and vice versa.
import { binary } from "@better-auth/util/binary"
const data = binary.encode("Hello World!");
const decoded = binary.decode(new Uint8Array([72, 101, 108, 108, 111]));Use rsa.generateKeyPair to create a new RSA key pair for encryption/decryption. By default, it generates a 2048-bit key using the SHA-256 hash algorithm. Supported modulus lengths are 2048 or 4096.
import { rsa } from '@better-auth/utils';
const keyPair = await rsa.generateKeyPair(2048, 'SHA-256');
// keyPair contains the CryptoKey objects for public and private keysUse the base64Url.decode method to convert a Base64Url string back into a Uint8Array. It automatically detects the alphabet based on the presence of URL-safe characters.
import { base64Url } from "@better-auth/utils";
const decoded = base64Url.decode("aGVsbG8td29ybGQ");
// Returns a Uint8Array