@nsec/crypto
v0.4.0
Published
Cryptographic engine for NullSec / ZVault (AES-256-GCM, RSA-OAEP-4096, Ed25519)
Downloads
274
Readme
@nsec/crypto
Cryptographic Engine for NullSec / ZVault (AES-256-GCM, RSA-OAEP-4096, Ed25519)
Overview • Cryptographic Architecture • Installation • API Reference • Security Specifications
Overview
@nsec/crypto is the zero-knowledge cryptographic engine powering the NullSec ecosystem. It provides the building blocks for:
- Envelope Encryption: Bulk secrets encrypted with AES-256-GCM; symmetric keys wrapped per-user with RSA-OAEP-4096.
- Service Token Cryptography: Zero-knowledge service token envelopes derived via SHA-256 and authenticated with AES-256-GCM.
- Identity & Signatures: Request signing and identity verification using Ed25519 with deterministic JSON canonicalization.
- Dual-Runtime Support: Native Node.js
node:cryptoimplementation with transparent WebCrypto (crypto.subtle) fallback for Edge and Cloudflare Workers environments.
The server never has access to unencrypted project secrets or user private keys.
Installation
# With npm
npm install @nsec/crypto
# With pnpm
pnpm add @nsec/crypto
# With yarn
yarn add @nsec/cryptoCryptographic Architecture
┌──────────────────────────┐
│ Application Secrets │
│ { DATABASE_URL: "..." } │
└─────────────┬────────────┘
│
▼ AES-256-GCM
┌──────────────────────────┐
│ Encrypted Secrets Cipher │
└─────────────▲────────────┘
│
Master Project Key (256-bit)
┌────────┴────────┐
│ │
RSA-OAEP-4096 ▼ ▼ AES-256-GCM
┌───────────────────────────────┐ ┌────────────────────────────────┐
│ Wrapped Key for User A (Alice)│ │ Wrapped Key for Service Token │
└───────────────────────────────┘ └────────────────────────────────┘- Master Project Key: A random 256-bit symmetric key (
generateProjectKey()) is created per project/environment. - Secrets Encryption: Secrets dictionaries are serialized and encrypted with AES-256-GCM using a unique 96-bit IV and 128-bit authentication tag.
- Envelope Distribution:
- For team members: The Master Project Key is encrypted with the user's RSA-4096 public key (
RSA-OAEPwith SHA-256). - For CI/CD service tokens: The Master Project Key is encrypted with AES-256-GCM using a 256-bit key derived via SHA-256 from the secret service token.
- For team members: The Master Project Key is encrypted with the user's RSA-4096 public key (
- Authentication: All API requests are signed with the caller's Ed25519 private key over a canonicalized JSON payload and timestamp.
API Reference
1. Symmetric Encryption (AES-256-GCM)
generateProjectKey(): string
Generates a cryptographically secure 256-bit (32-byte) key encoded as Base64.
import { generateProjectKey } from '@nsec/crypto';
const projectKey = generateProjectKey();encryptProjectSecrets(secrets, projectKey): EncryptedSecretsPayload
Encrypts a key-value record of secrets.
import { encryptProjectSecrets, decryptProjectSecrets } from '@nsec/crypto';
const secrets = {
DATABASE_URL: 'postgres://user:pass@localhost:5432/db',
API_KEY: 'sk_live_123456789'
};
const encryptedPayload = encryptProjectSecrets(secrets, projectKey);
// {
// ciphertext: "...",
// iv: "...",
// tag: "...",
// version: 1
// }
const decrypted = decryptProjectSecrets(encryptedPayload, projectKey);
console.log(decrypted.DATABASE_URL);encryptProjectKeyForServiceToken(projectKey, serviceToken)
Derives a key via SHA-256 from a service token and wraps the project key using AES-256-GCM.
import {
encryptProjectKeyForServiceToken,
decryptProjectKeyWithServiceToken
} from '@nsec/crypto';
const token = 'zv_st_production_a8f9c0e2...';
const wrapped = encryptProjectKeyForServiceToken(projectKey, token);
const unwrappedKey = decryptProjectKeyWithServiceToken(wrapped, token);2. Asymmetric Key Operations
generateUserKeyPair(): Promise<UserKeyPair>
Generates a dual keypair: an Ed25519 pair for signing and an RSA-4096 pair for key encryption (SPKI / PKCS#8 PEM formats).
import { generateUserKeyPair } from '@nsec/crypto';
const { signing, encryption } = await generateUserKeyPair();
// signing.publicKey / signing.privateKey (Ed25519)
// encryption.publicKey / encryption.privateKey (RSA-4096)encryptProjectKeyForUser(projectKey, userPublicKeyPem)
Encrypts the Master Project Key for a specific user using RSA-OAEP with SHA-256 hashing.
import {
encryptProjectKeyForUser,
decryptProjectKeyWithUserKey
} from '@nsec/crypto';
const wrappedKey = encryptProjectKeyForUser(projectKey, user.encryptionPublicKey);
// Later, on the user's client machine:
const restoredKey = decryptProjectKeyWithUserKey(wrappedKey, userPrivateKeyPem);3. Digital Signatures (Ed25519)
signPayload<T>(payload, privateKeyPem, publicKeyPem): SignedMessage<T>
Signs an arbitrary JSON-serializable payload after deterministic key sorting and timestamping.
import { signPayload, verifySignature, verifySignatureAsync } from '@nsec/crypto';
const message = signPayload(
{ action: 'get_secrets', projectId: 'proj-123', environment: 'production' },
signingPrivateKeyPem,
signingPublicKeyPem
);
// Synchronous verification (Node.js)
const isValid = verifySignature(message);
// Asynchronous verification (Cross-runtime / Cloudflare Workers / WebCrypto)
const isValidAsync = await verifySignatureAsync(message);canonicalizeJson(obj: unknown): string
Produces deterministic, lexicographically sorted JSON without whitespace variations, preventing signature mismatch due to key reordering.
Security Specifications
| Mechanism | Primitive | Key Size / Parameters | Usage | |---|---|---|---| | Bulk Encryption | AES-256-GCM | 256-bit key, 96-bit random IV, 128-bit tag | Project secrets storage | | Envelope Encryption | RSA-OAEP | 4096-bit modulus, SHA-256 OAEP hash | User key distribution | | Token Envelopes | AES-256-GCM | SHA-256 derived key, 96-bit IV | CI/CD Service Token wrapping | | Digital Signatures | Ed25519 | Ed25519 (256-bit elliptic curve) | Client request authentication | | Canonicalization | RFC 8785 compliant sorting | Lexicographical UTF-8 | Signature deterministic inputs |
