HTTP Signature

1.4.0 · maintenance · verified Tue Apr 21

http-signature is a Node.js library providing a reference implementation for Joyent's HTTP Signature scheme. This scheme allows clients and servers to sign and verify HTTP messages to ensure authenticity and integrity. The package's latest version, 1.4.0, was published over two years ago (as of late 2023), indicating a low-cadence or maintenance status, despite high weekly download numbers. While still widely used, it's important to note that this library implements Joyent's specific scheme, which predates and differs from the more recent IETF RFC 9421 "HTTP Message Signatures" standard. Other libraries, such as `http-message-signatures`, implement the newer RFC. This package is primarily designed for CommonJS environments and does not natively support ESM imports.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates both client-side request signing and server-side signature verification using `http-signature` for a basic HTTPS request. It shows how to use `sign`, `parseRequest`, and `verifySignature` functions.

const fs = require('fs');
const https = require('https');
const httpSignature = require('http-signature');

// In a real application, manage keys securely, e.g., via environment variables or a KMS.
// For this example, create dummy key.pem and cert.pem files.
// echo '-----BEGIN RSA PRIVATE KEY-----
// ...your-private-key...
// -----END RSA PRIVATE KEY-----' > key.pem
// echo '-----BEGIN CERTIFICATE-----
// ...your-certificate...
// -----END CERTIFICATE-----' > cert.pem

const key = fs.readFileSync('./key.pem', 'ascii');

const options = {
  host: 'localhost',
  port: 8443,
  path: '/',
  method: 'GET',
  headers: {}
};

const req = https.request(options, function(res) {
  console.log('Client received status code:', res.statusCode);
  res.on('data', (d) => process.stdout.write(d));
  res.on('end', () => console.log('\nClient request complete.'));
});

httpSignature.sign(req, {
  key: key,
  keyId: 'client-key-id',
  keyPassphrase: process.env.KEY_PASSPHRASE ?? '' // Optional, if key is encrypted
});

req.end();

// --- Server-side (for testing the client) ---
const serverOptions = {
  key: fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
};

https.createServer(serverOptions, function (serverReq, serverRes) {
  let responseCode = 200;
  try {
    const parsed = httpSignature.parseRequest(serverReq);
    // For a real server, 'pub' would come from a trusted source based on parsed.keyId
    const pub = fs.readFileSync('./cert.pem', 'ascii'); // Using the same cert for simplicity

    if (!httpSignature.verifySignature(parsed, pub)) {
      responseCode = 401; // Unauthorized
      console.error('Server: Signature verification failed!');
    } else {
      console.log('Server: Signature verified successfully for keyId:', parsed.keyId);
    }
  } catch (e) {
    responseCode = 500;
    console.error('Server error processing signature:', e.message);
  }

  serverRes.writeHead(responseCode, { 'Content-Type': 'text/plain' });
  serverRes.end(responseCode === 200 ? 'Hello from signed server!' : 'Authentication failed.');
}).listen(8443, () => console.log('Server listening on port 8443...'));

view raw JSON →