
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
signature-login
Advanced tools
Cryptographic signature-based authentication using secp256k1 elliptic curve digital signatures
Simple, secure, and cross-platform cryptographic authentication without passwords
npm install signature-login
import { generateKeyPair, createAuth, verifyAuth } from "signature-login";
// 1. Generate cryptographic key pair
const { privateKey, publicKey } = generateKeyPair();
// 2. Create authentication signature (client-side)
const authHeaders = await createAuth(privateKey);
// 3. Verify signature (server-side)
const verifiedPublicKey = await verifyAuth(authHeaders);
if (verifiedPublicKey) {
console.log("✅ Authentication successful!");
console.log("User public key:", verifiedPublicKey);
} else {
console.log("❌ Authentication failed");
}
generateKeyPair()Generates a new secp256k1 key pair.
const { privateKey, publicKey } = generateKeyPair();
// privateKey: "a1b2c3d4..." (64 chars)
// publicKey: "02a1b2c3d4..." (66 chars, compressed)
createAuth(privateKeyHex)Creates authentication headers with timestamp and nonce for replay protection.
const auth = await createAuth(privateKey);
console.log(auth);
// {
// publickey: "02a1b2c3d4...",
// signature: "3045022100...",
// message: "1642680123456:a1b2c3d4e5f6...",
// timestamp: 1642680123456,
// nonce: "a1b2c3d4e5f6..."
// }
verifyAuth(authHeaders, maxAgeMs?)Verifies authentication headers. Returns public key if valid, null if invalid.
const result = await verifyAuth(authHeaders);
// Returns: publicKey string or null
// Custom timeout (default: 5 minutes)
const result = await verifyAuth(authHeaders, 10 * 60 * 1000); // 10 minutes
// Sign any message
const signature = await sign("Hello World", privateKey);
// Verify any signature
const isValid = await verify("Hello World", signature, publicKey);
// Hash function
const hash = await sha256("Hello World");
import express from "express";
import { verifyAuth } from "signature-login";
const app = express();
// Authentication middleware
const authMiddleware = async (req, res, next) => {
const authHeader = req.headers["x-signature-auth"];
if (!authHeader) {
return res.status(401).json({ error: "Missing authentication" });
}
try {
const authData = JSON.parse(authHeader);
const publicKey = await verifyAuth(authData);
if (!publicKey) {
return res.status(401).json({ error: "Invalid signature" });
}
req.userPublicKey = publicKey;
next();
} catch (error) {
res.status(400).json({ error: "Malformed auth header" });
}
};
// Protected route
app.get("/protected", authMiddleware, (req, res) => {
res.json({
message: "Success!",
user: req.userPublicKey,
});
});
<!DOCTYPE html>
<html>
<head>
<script type="module">
import {
generateKeyPair,
createAuth,
} from "https://unpkg.com/signature-login@latest/index.js";
async function login() {
// Generate or load existing keys
const { privateKey } = generateKeyPair();
// Create auth signature
const auth = await createAuth(privateKey);
// Send to server
fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Signature-Auth": JSON.stringify(auth),
},
});
}
</script>
</head>
</html>
Client Server
------ ------
generateKeyPair() ──────────────▶ Store publicKey in database
│
▼
createAuth(privateKey) ──────────▶ verifyAuth(authHeaders)
│ │
▼ ▼
Send signature ─────────────────▶ Returns publicKey or null
import { sign, verify } from "signature-login";
// Sign custom data
const data = JSON.stringify({ action: "transfer", amount: 100 });
const signature = await sign(data, privateKey);
// Verify later
const isValid = await verify(data, signature, publicKey);
// ❌ Don't store private keys in plain text
localStorage.setItem("privateKey", privateKey);
// ✅ Use secure storage
const encryptedKey = await encrypt(privateKey, userPassword);
localStorage.setItem("encryptedKey", encryptedKey);
// ✅ Or use hardware wallets, secure enclaves, etc.
Made with ❤️ for the crypto community
FAQs
signature-login
We found that signature-login demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.