Skip to content

Repository files navigation

Better Auth Utils

A simple typescript API for common auth utilities like hashing, encryption, encoding, and OTP generation. Built on top of Web Crypto APIs to provide a unified API for both Node.js (using the Crypto module) and web environments (using the Web Crypto API) through Conditional Exports.

pnpm add @better-auth/utils

Utilities at a Glance

utilities provided by @better-auth/utils:

UtilityDescription
HashHash inputs using sha family hash functions.
HMACHash inputs using HMAC with a secret key.
Random StringGenerate random strings with a specified length and charset.
RSAPerform encryption, decryption, signing, and verification with RSA keys.
ECDSAPerform signing and verification with ECDSA keys.
OTPGenerate and verify one-time passwords.
Base64Encode and decode data in base64 format.
HexEncode and decode data in hexadecimal format.
BinaryEncode and decode data in binary format.

Hash

Digest provides a way to hash an input using sha family hash functions. It wraps over crypto.digest and provide utilities to encode output in hex or base 64.

import{createHash}from"@better-auth/utils/hash"consthashBuffer=awaitcreateHash("SHA-256").digest("text");consthashInHex=awaitcreateHash("SHA-256","hex").digest("text");

To encode output in base64

consthashInBase64=awaitcreateHash("SHA-256","base64").digest("text");

HMAC

The HMAC utility allows you to securely hash data using a secret key and SHA family hash functions. It provides methods to sign, verify, and create a customized HMAC instance with specific hashing algorithms and encoding formats.

Create HMAC

To create an HMAC instance, use the createHMAC function. You can specify the SHA family algorithm ("SHA-256", "SHA-384", or "SHA-512") and the desired encoding format ("none", "hex", "base64", "base64url", or "base64urlnopad").

It takes a secret key and returns a key object which could be used to sign and verify data.

import{createHMAC}from'./hmac';consthmac=createHMAC("SHA-256","hex");// Customize algorithm and encoding

Import Key

The importKey method takes a secret key (string, buffer, or typed array) and returns a CryptoKey object that can be used for signing and verifying data.

constsecretKey="my-secret-key";// Can also be a buffer or TypedArrayconstkey=awaithmac.importKey(secretKey);

Sign

The sign method takes a secret key (or CryptoKey) and data to generate a signature. If you provide a raw secret key, it will automatically be imported.

constkey=awaithmac.importKey("my-secret-key");constsignature=awaithmac.sign(key,"text to sign");console.log(signature);// Encoded based on the selected encoding format (e.g., hex)

You could also directly sign using the raw string secret key.

constsignature2=awaithmac.sign("secret-key",{data: "text"});

Verify

The verify method checks if a given signature matches the data using the secret key. You can provide either a raw secret key or a CryptoKey.

constkey=awaithmac.importKey("my-secret-key");constisValid=awaithmac.verify(key,"text to sign",signature);console.log(isValid);// true or false

Random String

Random crypto secure string generator. It wraps over crypto.getRandomValues and provide utilities to generator based on length and charset.

  1. first create a random string generator with desired charset.
import{createRandomStringGenerator}from"@better-auth/utils/random"exportconstgenerateRandomString=createRandomStringGenerator("A-Z","0-9","a-z","-_")
  1. generate random string based on length.
constrandomString=generateRandomString(32)constrandomString2=generateRandomString(32,"A-Z","0-9")// override charset

RSA

RSA utilities provide a simple interface to work with RSA cryptographic operations, such as generating key pairs, encrypting and decrypting data, and signing and verifying messages.

Key Pair Generation

You can generate RSA key pairs with specified parameters. By default, the modulusLength is 2048 bits and the hash algorithm is SHA-256.

import{rsa}from"@better-auth/utils/rsa";constkeyPair=awaitrsa.generateKeyPair(2048,"SHA-256");const{ publicKey, privateKey }=keyPair;

Exporting Keys

Export a public or private key in your preferred format.

constjwk=awaitrsa.exportKey(publicKey,"jwk");constspki=awaitrsa.exportKey(publicKey,"spki");

Importing Keys

Import a key in the jwk format for specific usage (encrypt, decrypt, sign, or verify).

constimportedKey=awaitrsa.importKey(jwk,"encrypt");

Encryption

Encrypt sensitive data using an RSA public key. Input can be a string, ArrayBuffer, TypedArray or string.

constencryptedData=awaitrsa.encrypt(publicKey,"Sensitive data");

Decryption

Decrypt encrypted data using the corresponding RSA private key.

constdecryptedData=awaitrsa.decrypt(privateKey,encryptedData);constoriginalText=newTextDecoder().decode(decryptedData);

Signing

Sign a message using the RSA private key. Input can be a string, ArrayBuffer, or TypedArray.

constsignature=awaitrsa.sign(privateKey,"Message to sign");

Verifying

Verify a signature against the original data using the RSA public key.

constisValid=awaitrsa.verify(publicKey,{
signature,data: "Message to sign",});

ECDSA

ECDSA utilities provide a simple interface to perform key pair generation, signing, and verification using elliptic curve cryptography.

Key Pair Generation

You can generate ECDSA key pairs with your preferred curve. Supported curves are "P-256", "P-384", and "P-521".

import{ecdsa}from"@better-auth/utils/ecdsa";const{ privateKey, publicKey }=awaitecdsa.generateKeyPair("P-256");

Exporting Keys

Export a public or private key in your preferred format, such as pkcs8 or spki.

constexportedPrivateKey=awaitecdsa.exportKey(privateKey,"pkcs8");constexportedPublicKey=awaitecdsa.exportKey(publicKey,"spki");

Importing Keys

Import an ECDSA private or public key in the appropriate format. Public keys can also be provided as strings.

constimportedPrivateKey=awaitecdsa.importPrivateKey(exportedPrivateKey,"P-256");constimportedPublicKey=awaitecdsa.importPublicKey(exportedPublicKey,"P-256");

Signing

Sign data using the ECDSA private key. The input can be a string or ArrayBuffer. You can specify the hash algorithm, which defaults to "SHA-256".

constsignature=awaitecdsa.sign(privateKey,"Message to sign","SHA-256");

Verifying

Verify a signature against the original data using the ECDSA public key. Input can be a string or ArrayBuffer. Signature verification requires providing the signature, data, and hash algorithm (default: "SHA-256").

constisValid=awaitecdsa.verify(publicKey,{
signature,data: "Message to verify",hash: "SHA-256",});

OTP

The OTP utility provides a simple and secure way to generate and verify one-time passwords (OTPs), commonly used in multi-factor authentication (MFA) systems. It includes support for both HOTP (HMAC-based One-Time Password) and TOTP (Time-based One-Time Password) standards.

It's implemented based on RFC 4226 and RFC 6238.

Generating HOTP

HOTP generates a one-time password based on a counter value and a secret key. The counter should be incremented for each new OTP.

import{createOTP}from"@better-auth/utils/otp";constsecret="my-super-secret-key";constcounter=1234;constotp=createOTP(secret,{digits: 6,}).hotp(counter);

Generating TOTP

TOTP generates a one-time password based on the current time and a secret key. The time step is typically 30 seconds.

import{createOTP}from"@better-auth/utils/otp";constsecret="my-super-secret-key"constotp=createOTP(secret,{digits: 6,period: 30,}).totp();

Verifying TOTP

Verify a TOTP against the secret key and a specified time window. The default time window is 30 seconds.

import{createOTP}from"@better-auth/utils/otp";constsecret="my-super-secret-key"constisValid=createOTP(secret,{digits: 6,period: 30,}).verify(otp);

You can also specify the time window in seconds.

import{createOTP}from"@better-auth/utils";constisValid=createOTP(secret).verify(otp,{window: 60});

Generate URL for Authenticator App

Generate a URL for provisioning a TOTP secret key in an authenticator app.

  • issuer - The name of the service or app.
  • account - The user's email or username.
import{createOTP}from"@better-auth/utils/otp";constsecret="my-super-secret-key";constqrCodeUrl=createOTP(secret).url("my-app","user@email.com");

Base64

Base64 utilities provide a simple interface to encode and decode data in base64 format.

Encoding

Encode data in base64 format. Input can be a string, ArrayBuffer, or number-based TypedArray. BigInt typed arrays are not supported.

import{base64}from"@better-auth/utils/base64";constencodedData=base64.encode("Data to encode");

options:

  • padding - Include padding characters (=) at the end of the encoded string
constencodedData=base64.encode("Data to encode",{url: true,padding: false});

Decoding

Decode base64-encoded data. Input can be a string or ArrayBuffer.

constdecodedData=awaitbase64.decode(encodedData);

It automatically detects if the input is URL-safe and includes padding characters.

Base64Url

Url safe alternative

import{base64Url}from"@better-auth/utils/base64";constencodedData=base64Url.encode("Data to encode");

Hex

Hex utilities provide a simple interface to encode and decode data in hexadecimal format.

Encoding

Encode data in hexadecimal format. Input can be a string, ArrayBuffer, or number-based TypedArray. BigInt typed arrays are not supported.

import{hex}from"@better-auth/utils/hex";constencodedData=hex.encode("Data to encode");

Decoding

Decode hexadecimal-encoded data into a string. Input can be a string, ArrayBuffer, or TypedArray. Uppercase and lowercase hexadecimal are both accepted.

constdecodedData=hex.decode(encodedData);

Converting to bytes

Convert a hexadecimal string into its raw bytes. Use this when the decoded value is binary data, such as a signature or key, rather than UTF-8 text.

constbytes=hex.toBytes("48656c6c6f");// Uint8Array([72, 101, 108, 108, 111])

Binary

A utilities provide a simple interface to encode and decode data in binary format. It uses TextEncode and TextDecoder to encode and decode data respectively.

Encoding

import{binary}from"@better-auth/util/binary"constdata=binary.encode("Hello World!")

Decoding

import{binary}from"@better-auth/util/binary"constdata=binary.decode(newUnit8Array([[72,101,108,108,111]]))

License

MIT

About

A simple TypeScript API for common auth related operations built on top of Web Crypto API.

Resources

Stars

232 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages