Cryptography in TypeScript: Encryption and Hashing
Modern web development is unthinkable without ensuring data security. TypeScript, as a strictly typed superset of JavaScript, provides developers with powerful tools for implementing cryptographic algorithms. In this article, we will look at the main encryption and hashing methods available in the TypeScript ecosystem and show how to apply them in practice.
Why is cryptography important in TypeScript?
TypeScript is widely used for both frontend and backend (via Node.js). In both cases, there is a need to protect confidential data: user passwords, authentication tokens, message content. Without proper cryptographic protection, data can be intercepted or compromised.
Cryptography in TypeScript solves three main tasks:
- Confidentiality — encrypting data so that outsiders cannot read it.
- Integrity — guaranteeing that data has not been altered during transmission.
- Authentication — verifying the authenticity of the data source.
Main cryptographic libraries for TypeScript
In TypeScript, you can use both built-in browser APIs and third-party libraries. Let's look at the most popular options:
1. Web Crypto API (built into the browser)
A standard API available in modern browsers and Node.js (from version 15). Does not require installing additional packages. Supports AES, RSA, SHA, and much more.
2. crypto (Node.js library)
A built-in Node.js module that provides a wide range of cryptographic functions. For TypeScript, you need to install types: npm install @types/node.
3. bcrypt / bcryptjs
A specialized library for password hashing. Recommended for storing user passwords due to its built-in salt protection.
4. tweetnacl / nacl
A library for public-key encryption (NaCl). It is known for high performance and ease of use.
Data Encryption in TypeScript
Let's look at two main types of encryption: symmetric (one key) and asymmetric (key pair).
Symmetric Encryption with AES-GCM
AES (Advanced Encryption Standard) in GCM mode provides both encryption and data integrity verification. Example implementation in TypeScript using the Web Crypto API:
// AES-GCM encryption functionasync function encryptAESGCM( plaintext: string, password: string): Promise<{ iv: Uint8Array; ciphertext: Uint8Array }> { const encoder = new TextEncoder(); const keyMaterial = await crypto.subtle.importKey( 'raw', encoder.encode(password), 'PBKDF2', false, ['deriveBits', 'deriveKey'] );
const key = await crypto.subtle.deriveKey( { name: 'PBKDF2', salt: encoder.encode('my-salt'), iterations: 100000, hash: 'SHA-256', }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt'] );
const iv = crypto.getRandomValues(new Uint8Array(12)); const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, key, encoder.encode(plaintext) );
return { iv, ciphertext: new Uint8Array(encrypted), };}
// Usage exampleconst { iv, ciphertext } = await encryptAESGCM('Secret message', 'my-password');console.log('Encrypted data:', ciphertext);Asymmetric Encryption with RSA-OAEP
RSA uses a key pair: a public key for encryption and a private key for decryption. Example of key generation and encryption:
// Generating an RSA key pairasync function generateRSAKeyPair(): Promise<CryptoKeyPair> { return await crypto.subtle.generateKey( { name: