Node Forge Cryptography and TLS Library
Node Forge is a comprehensive JavaScript library providing native implementations of cryptographic tools, network transports (like TLS, HTTP, SSH), and PKI components. It supports a wide array of ciphers (AES, DES), message digests (SHA-1, SHA-256, MD5), and PKI standards (X.509, PKCS# series). The current stable version is 1.4.0, which continues to build on its CommonJS module structure for Node.js and UMD bundles for browser environments. Its key differentiators include its entirely JavaScript-native implementation, which avoids native dependencies, and its extensive feature set for both client-side and server-side cryptographic operations, from generating RSA key pairs to parsing X.509 certificates.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'pki')
cause Attempting to access a submodule (like `pki`) before the main `forge` object has been correctly imported or initialized.fixEnsure `forge` is correctly imported as a default export (`import forge from 'node-forge';`) or required (`const forge = require('node-forge');`). Submodules are then accessed via `forge.pki`. -
ReferenceError: require is not defined
cause Attempting to use `require('node-forge')` in a browser environment without a module bundler like Webpack or Rollup, or in an ESM-only Node.js context without proper configuration.fixFor browsers, use the UMD bundles via a `<script>` tag (e.g., `<script src="https://cdn.jsdelivr.net/npm/node-forge@1.0.0/dist/forge.min.js"></script>`). For ESM Node.js, use `import forge from 'node-forge';`. -
TypeError: forge.md.sha256.create is not a function
cause Incorrectly calling `create()` on the message digest object, or trying to use a method that doesn't exist on the specific digest.fixEnsure you are calling `.create()` on the *algorithm factory* itself, e.g., `forge.md.sha256.create()`. Also verify the algorithm name is correct and supported.
Warnings
- breaking Node Forge transitioned from a monolithic 0.6.x branch with standalone files to a CommonJS module structure in 1.x. The 0.6.x branch is no longer regularly updated or maintained, and new projects should use the 1.x series. Code written for 0.6.x will require import and API adjustments.
- gotcha As a cryptographic library, it is critical to consult and thoroughly understand the 'Security Considerations' section of the documentation. Misuse of cryptographic primitives can lead to severe security vulnerabilities. Always use recommended best practices and ensure randomness sources are truly secure.
- gotcha Node Forge uses a CommonJS module structure for Node.js. When used in an ESM context (`'type': 'module'` or `.mjs` files), it typically requires `import forge from 'node-forge';` (default import interop). Direct named imports are not available, which can be a common source of confusion for modern JavaScript developers.
- gotcha When using Node Forge in web browsers via CDN or bundled files, it synchronously creates a global `forge` object. This can potentially conflict with other scripts or lead to unintended global pollution if not managed carefully.
Install
-
npm install node-forge -
yarn add node-forge -
pnpm add node-forge
Imports
- forge
import { forge } from 'node-forge';import forge from 'node-forge'; // or for CommonJS: const forge = require('node-forge'); - pki
import { pki } from 'node-forge';import forge from 'node-forge'; const pki = forge.pki;
- md.sha256
import { sha256 } from 'node-forge/lib/sha256';import forge from 'node-forge'; const sha256 = forge.md.sha256.create();
Quickstart
import forge from 'node-forge';
async function generateAndExportRSAKeypair() {
console.log('Generating RSA key pair...');
const keys = await new Promise((resolve) => {
forge.pki.rsa.generateKeyPair({ bits: 2048, workers: -1 }, (err, keypair) => {
if (err) throw err;
resolve(keypair);
});
});
const publicKeyPem = forge.pki.publicKeyToPem(keys.publicKey);
const privateKeyPem = forge.pki.privateKeyToPem(keys.privateKey);
console.log('\n--- Public Key PEM ---');
console.log(publicKeyPem);
console.log('\n--- Private Key PEM ---');
console.log(privateKeyPem);
// Example of creating a self-signed certificate
const cert = forge.pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = '01';
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
const attrs = [
{ name: 'commonName', value: 'example.org' },
{ name: 'countryName', value: 'US' },
{ shortName: 'ST', value: 'Virginia' },
{ name: 'organizationName', value: 'Example' }
];
cert.setSubject(attrs);
cert.setIssuer(attrs);
cert.setExtensions([
{ name: 'basicConstraints', cA: true },
{ name: 'keyUsage', digitalSignature: true, keyEncipherment: true, dataEncipherment: true },
{ name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true },
{ name: 'nsCertType', sslCPS: true, sslBSS: true, emailCA: true },
{ name: 'subjectAltName', altNames: [{ type: 6, value: 'http://example.org/' }, { type: 7, ip: '127.0.0.1' }]},
{ name: 'subjectKeyIdentifier' }
]);
// Sign the certificate with the private key
cert.sign(keys.privateKey, forge.md.sha256.create());
const pem = forge.pki.certificateToPem(cert);
console.log('\n--- Self-Signed Certificate PEM ---');
console.log(pem);
}
generateAndExportRSAKeypair().catch(console.error);