npm package: @lowlighter/crypto
Description: Features based upon Web Crypto APIs
Author: lowlighter
Latest version: 2.0.0

# 🧮 Cryptographic utilities

[![JSR](https://jsr.io/badges/@libs/crypto)](https://jsr.io/@libs/crypto) [![JSR Score](https://jsr.io/badges/@libs/crypto/score)](https://jsr.io/@libs/crypto)
[![NPM](https://img.shields.io/npm/v/@lowlighter%2Fcrypto?logo=npm&labelColor=cb0000&color=183e4e)](https://www.npmjs.com/package/@lowlighter/crypto) [![Coverage](https://libs-coverage.lecoq.io/crypto/badge.svg)](https://libs-coverage.lecoq.io/crypto)

## 🔑 Time-based One-Time Password (TOTP)

Issue a new TOTP secret with metadata (issuer, account, image, etc.).

- [`🦕 Playground`](https://libs.lecoq.io/crypto/totp)
- [`📚 Documentation`](https://jsr.io/@libs/crypto/doc/totp/~)

## 📑 Examples

```ts
import { otpauth, otpsecret, verify } from "./totp.ts"
import { qrcode } from "jsr:@libs/qrcode"

// Issue a new TOTP secret
const secret = otpsecret()
const url = otpauth({ issuer: "example.com", account: "alice", secret })
console.log(`Please scan the following QR Code:`)
qrcode(url.href, { output: "console" })

// Verify a TOTP token
const token = prompt("Please enter the token generated by your app:")!
console.assert(await verify({ token, secret }))
```

### ✨ Features

- Has no external dependencies.
- Is lightweight.

This library is based on the well-written article of [@rajat-sr](https://github.com/rajat-sr) [How To Implement Google Authenticator Two Factor Auth in JavaScript](https://hackernoon.com/how-to-implement-google-authenticator-two-factor-auth-in-javascript-091wy3vh3)

## 🔐 Symmetric encryption (using AES-GCM 256 with a PBKDF2 derived key)

- [`🦕 Playground`](https://libs.lecoq.io/crypto/encryption)
- [`📚 Documentation`](https://jsr.io/@libs/crypto/doc/encryption/~)

## 📑 Examples

```ts
import { decrypt, encrypt, exportKey, importKey } from "./encryption.ts"

// Generate a key. Same seed and salt combination will always yield the same key
const key = await exportKey({ seed: "hello", salt: "world" })
console.assert(key === "664d43091e7905723fc92a4c38f58e9aeff6d822488eb07d6b11bcfc2468f48a")

// Encrypt a message
const message = "🍱 bento"
const secret = await encrypt(message, { key, length: 512 })
console.assert(secret !== message)

// Encrypted messages are different each time and can also obfuscate the original message size
console.assert(secret !== await encrypt(message, { key, length: 512 }))
console.assert(secret.length === 512)

// Decrypt a message
const decrypted = await decrypt(secret, { key })
console.assert(decrypted === message)
```

### ✨ Features

- Use the native [`Web Crypto`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) APIs.
- Uses a [`AES-GCM 256-bits`](https://en.wikipedia.org/wiki/Galois/Counter_Mode) with [`PBKDF2`](https://en.wikipedia.org/wiki/PBKDF2)-derived key to encrypt and decrypt messages.
  - Encrypted messages are different each time thanks to an [initialization vector](https://en.wikipedia.org/wiki/Initialization_vector).
  - The derived keys from a given `seed`/`password` are always the same.
- Includes functionalities to introduce additional entropy:
  - Support for [SHA-256](https://en.wikipedia.org/wiki/SHA-2) to guarantee integrity.
  - Support for retaining the stored size to help verify integrity _(for messages with length < 255)_
  - Support for adding padding to force length be `256` or `512` bytes and obfuscate the original size _(can be disabled using `0` as value)_

## 📜 License and credits

```plaintext
Copyright (c) Simon Lecoq <@lowlighter>. (MIT License)
https://github.com/lowlighter/libs/blob/main/LICENSE
```

> [!CAUTION]
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND
>
> The author is not responsible for any damage that could be caused by the use of this library.
> It is your responsibility to use it properly and to understand the security implications of the choices you make.