npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

encryption-helpers

v22.0.0

Published

Angular encryption utilities: symmetric (AES) and asymmetric (RSA-OAEP) encryption services, encrypted-string detection, and secure random helpers

Readme

Encryption Helpers

Angular encryption utilities: symmetric (AES) and asymmetric (RSA-OAEP) encryption services, an encrypted-string detector, and cryptographically-secure random helpers.

Installation

npm install encryption-helpers

Configuration

The symmetric service derives its default key from the app id you provide via EncryptionHelpersModule.forRoot(...). If no app id is provided, a warning is logged and encrypt/decrypt return empty/null.

import { NgModule } from '@angular/core';
import { EncryptionHelpersModule } from 'encryption-helpers';

@NgModule({
  imports: [
    EncryptionHelpersModule.forRoot({ appId: '550e8400-e29b-41d4-a716-446655440000' })
  ]
})
export class AppModule { }

Exports

| File | Exports | |------|---------| | symmetrical-encryption.service.ts | SymmetricalEncryptionService | | asymmetrical-encryption.service.ts | AsymmetricalEncryptionService | | encryption-test.service.ts | EncryptionTestService | | random.ts | Random, RandomNumber, RandomNumbers, RandomNumbersUnique, RandomStr, RandomSignature, UUID, UUID_STR | | encryption-helpers.module.ts | EncryptionHelpersModule | | models/encryption-config.model.ts | EncryptionConfig, EncryptionConfigInterface | | models/encryption-config.token.ts | ENCRYPTION_CONFIG_TOKEN | | app.service.ts | AppService |


SymmetricalEncryptionService (AES)

Fast AES encryption for data at rest. Backed by crypto-js.

Implementation

  • Algorithm: AES with keySize: 16, mode: ECB, padding: Pkcs7.
  • Key/IV: derived from the provided key string. Both the key and IV use the same value.
  • Key alignment: the key/IV UTF-8 WordArray is zero-padded up to a 4-byte boundary (alignKey) so any key length round-trips correctly (keys whose byte length isn't a multiple of 4 previously failed silently).
  • Serialization: encrypt runs JSON.stringify(str) internally — pass any value; decrypt returns the JSON string (parse it yourself if needed).
  • ⚠️ Security note: AES-ECB with a shared key/IV and an 8-char cipher key is deliberately weak for convenience. Do not use this for high-security payloads.

Methods

| Method | Params | Returns | Description | |--------|--------|---------|-------------| | encrypt | str: any, key = this.appID | string \| undefined | Encrypts (JSON-stringifies then AES-ECB). Returns '' if str or key is falsy; undefined on error. | | decrypt | str: string, key = this.appID | string \| null | Decrypts AES ciphertext back to the JSON string. Returns null if input/key falsy, on malformed ciphertext, or on empty result. | | generateCipherKey | — | string | 8-char random key from two RandomSignature() values. | | createSignature | url: string, len = 16 | string | SHA-256 of url, truncated to len chars, uppercase hex. | | normalizeURL | url: string | string | Strips http(s)://, www., and trailing slashes. | | generateSignature | url: string | string | SHA-256 hex of the normalized URL (stable across protocol/www/trailing-slash variants). |

Samples

import { Component, inject } from '@angular/core';
import { SymmetricalEncryptionService } from 'encryption-helpers';

@Component({ selector: 'app-demo', template: '...' })
export class DemoComponent {
  private enc = inject(SymmetricalEncryptionService);

  roundTrip() {
    const cipher = this.enc.encrypt({ secret: 'sensitive', id: 123 });
    console.log(cipher);                       // base64 AES ciphertext
    const plain = this.enc.decrypt(cipher!);   // '{"secret":"sensitive","id":123}'
    console.log(JSON.parse(plain!));           // { secret: 'sensitive', id: 123 }
  }

  signatures() {
    this.enc.createSignature('https://example.com/path');       // 16-char uppercase hex
    this.enc.createSignature('https://example.com/path', 8);    // custom length
    // normalizeURL strips protocol/www/trailing slash
    this.enc.normalizeURL('https://www.example.com/path/');     // 'example.com/path'
    // generateSignature is stable regardless of protocol/www/trailing-slash form
    this.enc.generateSignature('https://www.example.com/path/') ===
      this.enc.generateSignature('http://example.com/path');    // true
  }
}

AsymmetricalEncryptionService (RSA-OAEP)

Public/private key encryption for secure key exchange and payload encryption. Backed by the Web Crypto API (crypto.subtle) and returns RxJS Observables.

Implementation

  • Algorithm: RSA-OAEP, modulusLength 1024/2048/4096 (default 2048), publicExponent 65537, hash SHA-256.
  • Key usability: keys are extractable with ["encrypt", "decrypt"].
  • Encryption output: encryptData returns the ciphertext as a base64 string (not raw bytes).
  • Key formats: PEM helpers support pkcs8/spki/raw formats.

Methods

| Method | Params | Returns | Description | |--------|--------|---------|-------------| | generateKeyPair | modulusLength = 2048 | Observable<CryptoKeyPair> | Generates an RSA-OAEP key pair. | | encryptData | publicKey: CryptoKey, data: string | Observable<string> | Encrypts a string; returns base64 ciphertext. | | decryptData | privateKey: CryptoKey, encryptedData: string | Observable<string> | Decrypts base64 ciphertext back to a string. | | pemToArrayBuffer | pem: string | ArrayBuffer | Parses a PEM string (strips headers/footers/newlines, base64-decodes). | | base64ToArrayBuffer | base64: string | ArrayBuffer | Decodes a base64 string. | | arrayBufferToBase64 | buffer: ArrayBuffer | string | Encodes bytes to base64. | | base64ToPEM | base64Key: string, publicKey = true | string | Wraps base64 into BEGIN/END PUBLIC/PRIVATE KEY PEM with 64-char lines. | | pemToCryptoKey | pem, algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[], format = "pkcs8" | Observable<CryptoKey> | Imports a PEM key via crypto.subtle.importKey. |

Samples

import { Component, inject } from '@angular/core';
import { firstValueFrom } from 'rxjs';
import { AsymmetricalEncryptionService } from 'encryption-helpers';

@Component({ selector: 'app-rsa-demo', template: '...' })
export class RsaDemoComponent {
  private rsa = inject(AsymmetricalEncryptionService);

  async fullRoundTrip() {
    const { publicKey, privateKey } = await firstValueFrom(this.rsa.generateKeyPair());

    const cipher = await firstValueFrom(this.rsa.encryptData(publicKey, 'hello secret'));
    const plain = await firstValueFrom(this.rsa.decryptData(privateKey, cipher));
    console.log(plain); // 'hello secret'
  }

  async importPem() {
    const algorithm: RsaHashedKeyGenParams = {
      name: 'RSA-OAEP',
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: 'SHA-256',
    };
    const { publicKey } = await firstValueFrom(this.rsa.generateKeyPair());
    const exported = await crypto.subtle.exportKey('spki', publicKey);
    const pem = this.rsa.base64ToPEM(this.rsa.arrayBufferToBase64(exported), true);

    const key = await firstValueFrom(
      this.rsa.pemToCryptoKey(pem, algorithm, true, ['encrypt'], 'spki')
    );
    // key is now usable with encryptData()
  }
}

EncryptionTestService

Heuristic detector for whether a string "looks" encrypted.

Methods

| Method | Params | Returns | Description | |--------|--------|---------|-------------| | isEncrypted | str: string | boolean | true if str matches a Base64 pattern, a hexadecimal pattern (even length), or has high entropy (> 60% unique characters). Non-string input → false. |

⚠️ Heuristic only — can produce false positives. Not for cryptographic verification.

import { inject } from '@angular/core';
import { EncryptionTestService } from 'encryption-helpers';

const test = inject(EncryptionTestService);
test.isEncrypted('U2FsdGVkX1+abc==');  // true (base64)
test.isEncrypted('deadbeef');          // true (hex)
test.isEncrypted('hello world');       // false (low entropy)

Random Utilities

Cryptographically secure random helpers using the Web Crypto API.

| Function | Signature | Returns | Description | |----------|-----------|---------|-------------| | Random | () | number | Random float in [0, 1) from crypto.getRandomValues. | | RandomNumber | (min, max) | number | Random integer in [min, max] inclusive. | | RandomNumbers | (min, max, length) | number[] | Array of length random integers in [min, max]. | | RandomNumbersUnique | (min, max, length) | number[] | Array of unique random integers; clamps length to range size; throws if max attempts exceeded. | | RandomStr | () | string | Base-36 string from a random Uint32Array value. | | RandomSignature | () | number | Random unsigned 32-bit integer. | | UUID | () | string | RFC-4122 UUID via crypto.randomUUID(). | | UUID_STR | () | string | Legacy (non-crypto-API) UUID fallback. |

import {
  Random, RandomNumber, RandomNumbers, RandomNumbersUnique,
  RandomStr, RandomSignature, UUID, UUID_STR,
} from 'encryption-helpers';

Random();                          // 0.7382
RandomNumber(1, 100);              // 42
RandomNumbers(1, 100, 5);          // [23, 87, 5, 64, 41]
RandomNumbersUnique(1, 50, 10);    // 10 unique numbers in 1..50
RandomStr();                       // '3k8d2j'
RandomSignature();                 // 2847593
UUID();                            // '550e8400-e29b-41d4-a716-446655440000'
UUID_STR();                        // 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'

Key Pair Generation on Mac

Generate an RSA key pair with the built-in openssl command-line tool (available on macOS and most Unix-like systems).

Generate the private key

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

Extract the public key

openssl rsa -pubout -in private_key.pem -out public_key.pem

View the keys

cat private_key.pem   # private key
cat public_key.pem    # public key

The resulting PEM files can be imported with AsymmetricalEncryptionService.pemToCryptoKey(...) for use in encryptData/decryptData.


Security Considerations

  1. Key management — never commit private keys or appId secrets to source control; use environment variables or a vault.
  2. Unique appId — must be unique per application.
  3. Client-side limitation — browser encryption is not a substitute for server-side security.
  4. AES-ECB weakness — the symmetric service uses ECB with a shared key/IV and short cipher key; avoid for high-security data.
  5. Key rotation — rotate RSA key pairs and appId periodically.
  6. EncryptionTestService — heuristic only; false positives possible.

Development

npm run test:encryption-helpers   # vitest suite
ng build encryption-helpers       # build with ng-packagr