README.md

September 6, 2025 ยท View on GitHub

npm version License: MIT TypeScript

A modern JavaScript/TypeScript cryptography library offering a comprehensive collection of hash functions, ciphers, encoders, and key derivation functions. Pure TypeScript implementation with full ES6 module support and CommonJS compatibility.

โœจ Features

  • ๐Ÿš€ Modern Implementation - Pure TypeScript with full type definitions
  • ๐Ÿ“ฆ Dual Module Support - ESM and CommonJS outputs for maximum compatibility
  • ๐ŸŒณ Tree-Shakeable - Import only what you need for optimal bundle size
  • ๐Ÿ”„ Streaming API - Process large data efficiently with progressive hashing/encryption
  • ๐Ÿ” Comprehensive Algorithms - Hash functions, symmetric ciphers, KDFs, and more
  • ๐Ÿ’ช Zero Dependencies - No external dependencies for lightweight integration
  • โšก High Performance - Optimized implementations with streaming support
  • ๐Ÿ›ก๏ธ Battle-Tested - Extensive test suite with known test vectors

๐Ÿ“ฆ Installation

# Using npm
npm install crypto-es

# Using yarn
yarn add crypto-es

# Using pnpm
pnpm add crypto-es

๐Ÿš€ Quick Start

Basic Hashing

import { MD5, SHA256, SHA512 } from 'crypto-es';

// Simple hashing
const hash1 = MD5('Hello World').toString();
// d41d8cd98f00b204e9800998ecf8427e

const hash2 = SHA256('Hello World').toString();
// a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b3f8b4c5cdcdcd9d0

const hash3 = SHA512('Hello World').toString();
// 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b

Basic Encryption

import { AES, DES, TripleDES } from 'crypto-es';

// AES encryption
const encrypted = AES.encrypt('Secret Message', 'secret key').toString();
const decrypted = AES.decrypt(encrypted, 'secret key').toString();

// DES encryption
const desEncrypted = DES.encrypt('Secret Message', 'secret key').toString();
const desDecrypted = DES.decrypt(desEncrypted, 'secret key').toString();

Encoding/Decoding

import { Base64, Hex, UTF8 } from 'crypto-es';

// Base64 encoding
const base64 = Base64.stringify(UTF8.parse('Hello World'));
// SGVsbG8gV29ybGQ=

// Hex encoding
const hex = Hex.stringify(UTF8.parse('Hello World'));
// 48656c6c6f20576f726c64

๐Ÿ“š Complete Algorithm Reference

Hash Functions

AlgorithmDescriptionOutput SizeUsage
MD5Legacy hash function128 bitsLegacy compatibility only
SHA1SHA-1 hash function160 bitsLegacy systems
SHA224SHA-2 family224 bitsModerate security
SHA256SHA-2 family256 bitsRecommended
SHA384SHA-2 family384 bitsHigh security
SHA512SHA-2 family512 bitsMaximum security
SHA3Latest SHA-3 standard224-512 bitsModern applications
RIPEMD160RIPEMD family160 bitsSpecialized use

Symmetric Ciphers

AlgorithmKey SizeBlock SizeDescription
AES128/192/256 bits128 bitsIndustry standard
DES56 bits64 bitsLegacy only
TripleDES168 bits64 bitsLegacy upgrade from DES
Rabbit128 bitsStreamHigh-performance stream cipher
RC4VariableStreamLegacy stream cipher
Blowfish32-448 bits64 bitsVariable key length

Key Derivation Functions

AlgorithmDescriptionUsage
PBKDF2Password-Based KDF v2Recommended for passwords
EvpKDFOpenSSL EVP KDFOpenSSL compatibility

Encoders

EncoderDescription
Base64Standard Base64 encoding
Base64urlURL-safe Base64 encoding
HexHexadecimal encoding
UTF8UTF-8 text encoding
UTF16UTF-16 text encoding
Latin1Latin-1 text encoding

Cipher Modes

ModeDescriptionIV Required
CBCCipher Block Chaining (default)Yes
ECBElectronic CodebookNo
CFBCipher FeedbackYes
OFBOutput FeedbackYes
CTRCounterYes

Padding Schemes

PaddingDescription
PKCS7PKCS#7 padding (default)
AnsiX923ANSI X9.23 padding
ISO10126ISO 10126 padding
ISO97971ISO/IEC 9797-1 padding
ZeroPaddingZero byte padding
NoPaddingNo padding

๐Ÿ“– Detailed Usage Guide

Hash Algorithms

MD5

import { MD5, HmacMD5 } from 'crypto-es';

// Basic hashing
const hash = MD5('message').toString();

// HMAC-MD5
const hmac = HmacMD5('message', 'secret key').toString();

// Progressive hashing
const hasher = MD5Algo.create();
hasher.update('message part 1');
hasher.update('message part 2');
const progressiveHash = hasher.finalize().toString();

SHA1

import { SHA1, HmacSHA1, SHA1Algo } from 'crypto-es';

// Basic hashing
const hash = SHA1('message').toString();

// HMAC-SHA1
const hmac = HmacSHA1('message', 'secret key').toString();

// Progressive hashing
const hasher = SHA1Algo.create();
hasher.update('large data chunk 1');
hasher.update('large data chunk 2');
const result = hasher.finalize().toString();

SHA224

import { SHA224, HmacSHA224 } from 'crypto-es';

// Basic hashing
const hash = SHA224('message').toString();

// HMAC-SHA224
const hmac = HmacSHA224('message', 'secret key').toString();

SHA256

import { SHA256, HmacSHA256, SHA256Algo } from 'crypto-es';

// Basic hashing
const hash = SHA256('message').toString();

// HMAC-SHA256 (commonly used for API authentication)
const hmac = HmacSHA256('message', 'secret key').toString();

// Progressive hashing for large files
const hasher = SHA256Algo.create();
hasher.update('chunk1');
hasher.update('chunk2');
hasher.update('chunk3');
const fileHash = hasher.finalize().toString();

// Different output formats
import { Hex, Base64 } from 'crypto-es';
const hashHex = SHA256('message').toString(Hex);
const hashBase64 = SHA256('message').toString(Base64);

SHA384

import { SHA384, HmacSHA384 } from 'crypto-es';

// Basic hashing
const hash = SHA384('message').toString();

// HMAC-SHA384
const hmac = HmacSHA384('message', 'secret key').toString();

SHA512

import { SHA512, HmacSHA512, SHA512Algo } from 'crypto-es';

// Basic hashing
const hash = SHA512('message').toString();

// HMAC-SHA512
const hmac = HmacSHA512('message', 'secret key').toString();

// Progressive hashing with typed arrays
import { WordArray } from 'crypto-es';
const hasher = SHA512Algo.create();
const data1 = WordArray.create(new Uint8Array([1, 2, 3, 4]));
const data2 = WordArray.create(new Uint8Array([5, 6, 7, 8]));
hasher.update(data1);
hasher.update(data2);
const result = hasher.finalize();

SHA3

import { SHA3 } from 'crypto-es';

// SHA3-256 (default)
const hash256 = SHA3('message').toString();

// SHA3-224
const hash224 = SHA3('message', { outputLength: 224 }).toString();

// SHA3-384
const hash384 = SHA3('message', { outputLength: 384 }).toString();

// SHA3-512
const hash512 = SHA3('message', { outputLength: 512 }).toString();

RIPEMD160

import { RIPEMD160, HmacRIPEMD160 } from 'crypto-es';

// Basic hashing
const hash = RIPEMD160('message').toString();

// HMAC-RIPEMD160
const hmac = HmacRIPEMD160('message', 'secret key').toString();

Symmetric Encryption

AES

import { AES, ECB, CBC, CFB, OFB, CTR, NoPadding, PKCS7 } from 'crypto-es';

// Simple encryption with password
const encrypted = AES.encrypt('Secret Message', 'password').toString();
const decrypted = AES.decrypt(encrypted, 'password').toString(UTF8);

// AES with specific key size (128/192/256 bits)
import { PBKDF2, WordArray } from 'crypto-es';
const key128 = PBKDF2('password', 'salt', { keySize: 128/32 });
const key192 = PBKDF2('password', 'salt', { keySize: 192/32 });
const key256 = PBKDF2('password', 'salt', { keySize: 256/32 });

// Encryption with different modes
const encrypted1 = AES.encrypt('message', key256, { mode: ECB }).toString();
const encrypted2 = AES.encrypt('message', key256, { mode: CBC }).toString();
const encrypted3 = AES.encrypt('message', key256, { mode: CFB }).toString();
const encrypted4 = AES.encrypt('message', key256, { mode: OFB }).toString();
const encrypted5 = AES.encrypt('message', key256, { mode: CTR }).toString();

// Custom IV (Initialization Vector)
const iv = WordArray.random(128/8);
const encrypted = AES.encrypt('message', key256, { iv: iv }).toString();

// Different padding schemes
const encrypted6 = AES.encrypt('message', key256, { padding: PKCS7 }).toString();
const encrypted7 = AES.encrypt('message', key256, { padding: NoPadding }).toString();

// Streaming encryption for large data
import { AESAlgo } from 'crypto-es';
const key = PBKDF2('password', 'salt', { keySize: 256/32 });
const iv = WordArray.random(128/8);
const aes = AESAlgo.createEncryptor(key, { iv: iv });

const part1 = aes.process('part 1 of data');
const part2 = aes.process('part 2 of data');
const part3 = aes.process('part 3 of data');
const encrypted = part1.concat(part2).concat(part3).concat(aes.finalize());

DES

import { DES, DESAlgo } from 'crypto-es';

// Simple DES encryption
const encrypted = DES.encrypt('Message', 'password').toString();
const decrypted = DES.decrypt(encrypted, 'password').toString(UTF8);

// DES with custom options
import { ECB, NoPadding } from 'crypto-es';
const encrypted = DES.encrypt('Message', 'password', {
  mode: ECB,
  padding: NoPadding
}).toString();

// Streaming DES
const des = DESAlgo.createEncryptor('password');
const encrypted = des.finalize('Message').toString();

TripleDES

import { TripleDES, TripleDESAlgo } from 'crypto-es';

// Simple 3DES encryption
const encrypted = TripleDES.encrypt('Message', 'password').toString();
const decrypted = TripleDES.decrypt(encrypted, 'password').toString(UTF8);

// 3DES with 192-bit key
import { PBKDF2 } from 'crypto-es';
const key = PBKDF2('password', 'salt', { keySize: 192/32 });
const encrypted = TripleDES.encrypt('Message', key).toString();

// Streaming 3DES
const cipher = TripleDESAlgo.createEncryptor(key);
const encrypted = cipher.finalize('Message').toString();

Rabbit

import { Rabbit, RabbitAlgo } from 'crypto-es';

// Simple Rabbit encryption
const encrypted = Rabbit.encrypt('Message', 'password').toString();
const decrypted = Rabbit.decrypt(encrypted, 'password').toString(UTF8);

// Rabbit with IV
import { WordArray } from 'crypto-es';
const key = WordArray.random(128/8);
const iv = WordArray.random(64/8);
const encrypted = Rabbit.encrypt('Message', key, { iv: iv }).toString();

// Streaming Rabbit
const cipher = RabbitAlgo.createEncryptor(key, { iv: iv });
const encrypted = cipher.finalize('Message').toString();

RC4

import { RC4, RC4Drop } from 'crypto-es';

// Simple RC4 encryption
const encrypted = RC4.encrypt('Message', 'password').toString();
const decrypted = RC4.decrypt(encrypted, 'password').toString(UTF8);

// RC4Drop (more secure variant)
const encrypted = RC4Drop.encrypt('Message', 'password').toString();
const decrypted = RC4Drop.decrypt(encrypted, 'password').toString(UTF8);

// RC4 with custom drop value
import { RC4DropAlgo } from 'crypto-es';
const cipher = RC4DropAlgo.createEncryptor('password', { drop: 3072/4 });
const encrypted = cipher.finalize('Message').toString();

Blowfish

import { Blowfish, BlowfishAlgo } from 'crypto-es';

// Simple Blowfish encryption
const encrypted = Blowfish.encrypt('Message', 'password').toString();
const decrypted = Blowfish.decrypt(encrypted, 'password').toString(UTF8);

// Blowfish with variable key length (32-448 bits)
import { PBKDF2 } from 'crypto-es';
const key128 = PBKDF2('password', 'salt', { keySize: 128/32 });
const key256 = PBKDF2('password', 'salt', { keySize: 256/32 });
const key448 = PBKDF2('password', 'salt', { keySize: 448/32 });

const encrypted1 = Blowfish.encrypt('Message', key128).toString();
const encrypted2 = Blowfish.encrypt('Message', key256).toString();
const encrypted3 = Blowfish.encrypt('Message', key448).toString();

Key Derivation Functions

PBKDF2

import { PBKDF2, SHA256Algo, SHA512Algo } from 'crypto-es';

// Basic PBKDF2 with default settings (SHA1, 1 iteration)
const key = PBKDF2('password', 'salt');

// PBKDF2 with custom settings
const key256 = PBKDF2('password', 'salt', {
  keySize: 256/32,        // 256-bit key
  iterations: 10000,      // 10,000 iterations
  hasher: SHA256Algo     // SHA256 hasher
});

const key512 = PBKDF2('password', 'salt', {
  keySize: 512/32,        // 512-bit key
  iterations: 100000,     // 100,000 iterations
  hasher: SHA512Algo     // SHA512 hasher
});

// Use for AES encryption
import { AES } from 'crypto-es';
const derivedKey = PBKDF2('mypassword', 'mysalt', {
  keySize: 256/32,
  iterations: 10000
});
const encrypted = AES.encrypt('Secret', derivedKey).toString();

EvpKDF

import { EvpKDF, MD5Algo, SHA256Algo } from 'crypto-es';

// Basic EvpKDF
const key = EvpKDF('password', 'salt');

// EvpKDF with custom settings
const key256 = EvpKDF('password', 'salt', {
  keySize: 256/32,
  iterations: 1000,
  hasher: SHA256Algo
});

// Compatible with OpenSSL EVP_BytesToKey
const opensslKey = EvpKDF('password', 'salt', {
  keySize: 256/32,
  ivSize: 128/32,
  hasher: MD5Algo
});

Encoders

Base64

import { Base64, UTF8, WordArray } from 'crypto-es';

// Encode string to Base64
const encoded = Base64.stringify(UTF8.parse('Hello World'));
// SGVsbG8gV29ybGQ=

// Decode Base64 to string
const decoded = UTF8.stringify(Base64.parse('SGVsbG8gV29ybGQ='));
// Hello World

// Base64 with WordArray
const wordArray = WordArray.create([0x48656c6c, 0x6f20576f, 0x726c6400], 11);
const base64 = Base64.stringify(wordArray);

Base64url

import { Base64url, UTF8 } from 'crypto-es';

// URL-safe Base64 encoding (no padding, - and _ instead of + and /)
const encoded = Base64url.stringify(UTF8.parse('Hello World??'));
// SGVsbG8gV29ybGQ_Pw

// Decode Base64url
const decoded = UTF8.stringify(Base64url.parse('SGVsbG8gV29ybGQ_Pw'));
// Hello World??

Hex

import { Hex, UTF8, WordArray } from 'crypto-es';

// Encode string to Hex
const encoded = Hex.stringify(UTF8.parse('Hello World'));
// 48656c6c6f20576f726c64

// Decode Hex to string
const decoded = UTF8.stringify(Hex.parse('48656c6c6f20576f726c64'));
// Hello World

// Hex with WordArray
const wordArray = WordArray.create([0x48656c6c, 0x6f20576f, 0x726c6400], 11);
const hex = Hex.stringify(wordArray);
// 48656c6c6f20576f726c64

UTF8

import { UTF8, WordArray } from 'crypto-es';

// Parse UTF8 string to WordArray
const wordArray = UTF8.parse('Hello World ไฝ ๅฅฝไธ–็•Œ');

// Stringify WordArray to UTF8
const utf8String = UTF8.stringify(wordArray);

// Handle special characters
const emoji = UTF8.parse('๐Ÿ˜€๐ŸŽ‰๐Ÿš€');
const back = UTF8.stringify(emoji);

UTF16

import { UTF16, UTF16BE, UTF16LE } from 'crypto-es';

// UTF16 Big Endian
const encodedBE = UTF16BE.stringify(UTF16BE.parse('Hello'));

// UTF16 Little Endian
const encodedLE = UTF16LE.stringify(UTF16LE.parse('Hello'));

// Auto-detect endianness
const encoded = UTF16.stringify(UTF16.parse('Hello'));

Latin1

import { Latin1 } from 'crypto-es';

// Parse Latin1 string to WordArray
const wordArray = Latin1.parse('Hello World');

// Stringify WordArray to Latin1
const latin1String = Latin1.stringify(wordArray);

Cipher Modes

CBC

import { AES, CBC, PKCS7 } from 'crypto-es';

// CBC mode (default)
const encrypted = AES.encrypt('message', 'password', {
  mode: CBC,
  padding: PKCS7
}).toString();

ECB

import { AES, ECB } from 'crypto-es';

// ECB mode (not recommended for security)
const encrypted = AES.encrypt('message', 'password', {
  mode: ECB
}).toString();

CFB

import { AES, CFB } from 'crypto-es';

// CFB mode
const encrypted = AES.encrypt('message', 'password', {
  mode: CFB
}).toString();

OFB

import { AES, OFB } from 'crypto-es';

// OFB mode
const encrypted = AES.encrypt('message', 'password', {
  mode: OFB
}).toString();

CTR

import { AES, CTR } from 'crypto-es';

// CTR mode
const encrypted = AES.encrypt('message', 'password', {
  mode: CTR
}).toString();

Padding Schemes

PKCS7

import { AES, PKCS7 } from 'crypto-es';

// PKCS7 padding (default)
const encrypted = AES.encrypt('message', 'password', {
  padding: PKCS7
}).toString();

AnsiX923

import { AES, AnsiX923 } from 'crypto-es';

// ANSI X9.23 padding
const encrypted = AES.encrypt('message', 'password', {
  padding: AnsiX923
}).toString();

ISO10126

import { AES, ISO10126 } from 'crypto-es';

// ISO 10126 padding
const encrypted = AES.encrypt('message', 'password', {
  padding: ISO10126
}).toString();

ISO97971

import { AES, ISO97971 } from 'crypto-es';

// ISO/IEC 9797-1 padding
const encrypted = AES.encrypt('message', 'password', {
  padding: ISO97971
}).toString();

ZeroPadding

import { AES, ZeroPadding } from 'crypto-es';

// Zero padding
const encrypted = AES.encrypt('message', 'password', {
  padding: ZeroPadding
}).toString();

NoPadding

import { AES, NoPadding, WordArray } from 'crypto-es';

// No padding (message must be multiple of block size)
const message = WordArray.create([0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]);
const encrypted = AES.encrypt(message, 'password', {
  padding: NoPadding
}).toString();

๐Ÿ”ง Advanced Topics

Working with WordArray

import { WordArray, UTF8, Hex, Base64 } from 'crypto-es';

// Create WordArray from different sources
const wa1 = WordArray.create([0x12345678, 0x9abcdef0]);
const wa2 = WordArray.random(16); // 16 random bytes
const wa3 = UTF8.parse('Hello World');
const wa4 = Hex.parse('48656c6c6f');
const wa5 = Base64.parse('SGVsbG8=');

// Concatenate WordArrays
const combined = wa1.concat(wa2).concat(wa3);

// Clone WordArray
const cloned = wa1.clone();

// Get bytes
const bytes = wa1.sigBytes;

// Convert to different formats
const hex = wa1.toString(Hex);
const base64 = wa1.toString(Base64);
const utf8 = wa1.toString(UTF8);

Streaming Large Files

import { SHA256Algo, AESAlgo, WordArray } from 'crypto-es';

// Hash large file in chunks
async function hashLargeFile(file: File): Promise<string> {
  const hasher = SHA256Algo.create();
  const chunkSize = 1024 * 1024; // 1MB chunks
  
  for (let offset = 0; offset < file.size; offset += chunkSize) {
    const chunk = file.slice(offset, offset + chunkSize);
    const arrayBuffer = await chunk.arrayBuffer();
    const wordArray = WordArray.create(arrayBuffer);
    hasher.update(wordArray);
  }
  
  return hasher.finalize().toString();
}

// Encrypt large data stream
function encryptStream(key: WordArray, iv: WordArray) {
  const cipher = AESAlgo.createEncryptor(key, { iv });
  
  return {
    process: (chunk: string) => cipher.process(chunk),
    finalize: () => cipher.finalize()
  };
}

Custom Cipher Configuration

import { AES, CBC, PKCS7, SerializableCipher, OpenSSLFormatter } from 'crypto-es';

// Create custom cipher configuration
const cipherParams = {
  mode: CBC,
  padding: PKCS7,
  format: OpenSSLFormatter,
  blockSize: 128/32,
  formatter: OpenSSLFormatter
};

// Use with encryption
const encrypted = AES.encrypt('message', 'password', cipherParams);

// Serialize/deserialize encrypted data
const serialized = encrypted.toString();
const deserialized = SerializableCipher.parse(serialized);

HMAC for API Authentication

import { HmacSHA256, Hex } from 'crypto-es';

// Create API signature
function createApiSignature(
  method: string,
  path: string,
  body: string,
  secret: string
): string {
  const message = `${method}\n${path}\n${body}`;
  return HmacSHA256(message, secret).toString(Hex);
}

// Verify webhook signature
function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = HmacSHA256(payload, secret).toString(Hex);
  return signature === expectedSignature;
}

Password Storage Best Practices

import { PBKDF2, SHA256Algo, WordArray, Hex } from 'crypto-es';

// Hash password for storage
function hashPassword(password: string): { hash: string; salt: string } {
  const salt = WordArray.random(128/8);
  const hash = PBKDF2(password, salt, {
    keySize: 256/32,
    iterations: 100000,
    hasher: SHA256Algo
  });
  
  return {
    hash: hash.toString(Hex),
    salt: salt.toString(Hex)
  };
}

// Verify password
function verifyPassword(
  password: string,
  storedHash: string,
  storedSalt: string
): boolean {
  const salt = Hex.parse(storedSalt);
  const hash = PBKDF2(password, salt, {
    keySize: 256/32,
    iterations: 100000,
    hasher: SHA256Algo
  });
  
  return hash.toString(Hex) === storedHash;
}

๐ŸŒ Browser & Node.js Compatibility

Browser Usage

<!-- Via CDN -->
<script src="https://unpkg.com/crypto-es@latest/dist/index.js"></script>
<script>
  const hash = cryptoEs.SHA256('message').toString();
</script>

Webpack Configuration

// webpack.config.js
module.exports = {
  resolve: {
    extensions: ['.ts', '.js'],
    fallback: {
      crypto: false // crypto-es doesn't need Node crypto
    }
  }
};

Vite Configuration

// vite.config.js
export default {
  optimizeDeps: {
    include: ['crypto-es']
  }
};

TypeScript Configuration

// tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  }
}

๐Ÿ“Š API Reference

Core Classes

WordArray

class WordArray {
  static create(words?: number[], sigBytes?: number): WordArray;
  static random(nBytes: number): WordArray;
  
  sigBytes: number;
  words: number[];
  
  concat(wordArray: WordArray): WordArray;
  clone(): WordArray;
  toString(encoder?: Encoder): string;
}

CipherParams

class CipherParams {
  ciphertext: WordArray;
  key?: WordArray;
  iv?: WordArray;
  salt?: WordArray;
  algorithm?: Cipher;
  mode?: Mode;
  padding?: Padding;
  blockSize?: number;
  formatter?: Formatter;
  
  static create(cipherParams: Partial<CipherParams>): CipherParams;
  toString(formatter?: Formatter): string;
}

Hasher

interface Hasher {
  update(messageUpdate: string | WordArray): Hasher;
  finalize(messageUpdate?: string | WordArray): WordArray;
}

Cipher

interface Cipher {
  encrypt(message: string | WordArray, key: string | WordArray, cfg?: CipherCfg): CipherParams;
  decrypt(ciphertext: string | CipherParams, key: string | WordArray, cfg?: CipherCfg): WordArray;
}

๐Ÿš€ Performance Tips

  1. Use streaming for large data: Process data in chunks with update() and finalize()
  2. Choose appropriate algorithms: SHA256 for general hashing, AES for encryption
  3. Reuse hasher instances: Create once, reset and reuse for multiple operations
  4. Use typed arrays: Convert ArrayBuffer to WordArray for better performance
  5. Enable tree-shaking: Import only needed algorithms to reduce bundle size

๐Ÿ”’ Security Considerations

โš ๏ธ Important Security Notes

  1. Never use MD5 or SHA1 for security: These are broken algorithms, use SHA256 or higher
  2. Always use authenticated encryption: Combine encryption with HMAC for integrity
  3. Use sufficient iterations for PBKDF2: Minimum 10,000, recommend 100,000+
  4. Generate random IVs: Never reuse IVs with the same key
  5. Use constant-time comparison: Prevent timing attacks when comparing hashes
  6. Store passwords properly: Use PBKDF2 with salt, never store plain text
  7. Avoid ECB mode: Use CBC, CTR, or GCM modes instead
  • Hashing: SHA256, SHA512, SHA3
  • Encryption: AES with 256-bit keys
  • Key Derivation: PBKDF2 with 100,000+ iterations
  • HMAC: HmacSHA256 or HmacSHA512

๐Ÿ› ๏ธ Development

Setup

# Clone repository
git clone https://github.com/entronad/crypto-es.git
cd crypto-es

# Install dependencies
npm install

# Build library
npm run build

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

Available Scripts

  • npm run build - Build the library
  • npm run build:watch - Build in watch mode
  • npm test - Run tests
  • npm run test:watch - Run tests in watch mode
  • npm run test:coverage - Generate coverage report
  • npm run typecheck - Check TypeScript types
  • npm run clean - Clean build artifacts

Project Structure

crypto-es/
โ”œโ”€โ”€ src/                # Source code
โ”‚   โ”œโ”€โ”€ core.ts        # Core utilities
โ”‚   โ”œโ”€โ”€ cipher-core.ts # Cipher base classes
โ”‚   โ”œโ”€โ”€ md5.ts         # MD5 implementation
โ”‚   โ”œโ”€โ”€ sha256.ts      # SHA256 implementation
โ”‚   โ”œโ”€โ”€ aes.ts         # AES implementation
โ”‚   โ””โ”€โ”€ ...            # Other algorithms
โ”œโ”€โ”€ __tests__/         # Test files
โ”œโ”€โ”€ dist/              # Built output
โ”‚   โ”œโ”€โ”€ *.mjs         # ESM modules
โ”‚   โ”œโ”€โ”€ *.cjs         # CommonJS modules
โ”‚   โ””โ”€โ”€ *.d.ts        # TypeScript definitions
โ””โ”€โ”€ package.json       # Package configuration

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Guidelines

  • Write tests for new features
  • Ensure all tests pass
  • Follow existing code style
  • Update documentation as needed
  • Add yourself to contributors

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT ยฉ LIN Chen


Note: This library is for legitimate use only. Always follow your local laws and regulations regarding cryptography.