RSA Digital Signature Tool (javascript, written by Claude Code)
envgap__claude-code__javascript-t1-12
Written by a coding agent; not on GitHubWritten 2026-02-27
01 / FAILURE SIGNATURE
As the study recorded it
No identifying execution failure has been captured.
Not a benchmark task.
- The project already builds and runs before the fix, so there is nothing to repair.
02 / ENVIRONMENT RECIPE
- Base commit
Not freshly verified- Manifest
package.json- Reproduce
Awaiting issue-specific recipe- Run under trace
Awaiting a meaningful runtime command
03 / TASK AND FAILURE
claude-code/javascript-t1 #12 · read the task the agent was given
Claude Code wrote this javascript project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written. Task given to the agent: TASK: RSA Digital Signature Tool Write a program that generates RSA key pairs and uses them to create and verify digital signatures on files, ensuring document authenticity and integrity. FUNCTIONAL REQUIREMENTS: - Support three subcommands: keygen, sign, and verify - keygen: Generate an RSA key pair (2048 or 4096 bit, selectable via --bits flag, default 2048) and save the private key and public key as separate PEM files - sign: Accept a file path and private key path, compute a SHA-256 hash of the file, sign it with RSA-PSS padding, and save the signature as a separate .sig file - verify: Accept a file path, signature file path, and public key path, then verify the signature and print whether it is valid or invalid with details - Support signing multiple files at once by accepting a directory path via --batch flag - Support a --output flag to specify where to save generated keys or signatures - Display key information: key size, fingerprint (SHA-256 hash of public key), and creation timestamp - Support exporting the public key in both PEM and DER formats via --format flag - Print detailed results to console: for signing show the file hash and signature size, for verification show match/mismatch status and key details - If no arguments are given, generate a sample key pair, create a sample text file, sign it, verify the signature, then tamper with the file and show that verification fails - Handle errors gracefully: invalid key format, mismatched key/signature, corrupted files, unsupported key sizes Create a complete JavaScript project for a clean Ubuntu 22.04 machine with only Node.js 20+ (LTS) installed. Include: - Source code - package.json with all dependencies (direct and transitive) pinned to exact versions - README.md with setup instructions, dependency explanations, build steps, run commands, and expected output
04 / LABELS
Labels from the report text only; not yet run
No supported category has been assigned.
Label rules and the text that matched
[]
05 / FILES
The project as the agent wrote it
3 files, exactly as written, before any repair.
package.json
{
"name": "rsa-signer",
"version": "1.0.0",
"description": "RSA Digital Signature Tool using Node.js built-in crypto",
"main": "signer.js",
"bin": {
"rsa-signer": "./signer.js"
},
"scripts": {
"start": "node signer.js"
},
"keywords": ["rsa", "signature", "crypto"],
"license": "MIT",
"engines": {
"node": ">=16.0.0"
}
}
README.md
# RSA Digital Signature Tool (JavaScript - Node.js crypto) Sign and verify files using RSA-2048/4096 with SHA-256 using Node.js built-in crypto. ## Usage ```bash # Generate key pair node signer.js keygen --bits 2048 # Sign a file node signer.js sign myfile.txt --key private.pem # Verify a signature node signer.js verify myfile.txt --key public.pem # Run demo (no arguments) node signer.js ``` ## Dependencies - Node.js 16+ (no external dependencies, uses built-in crypto)
signer.js
#!/usr/bin/env node
"use strict";
/**
* RSA Digital Signature Tool using Node.js built-in crypto module.
* Sign and verify files using RSA-2048/4096 with SHA-256.
*/
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
function generateKeys(privateKeyPath, publicKeyPath, keySize = 2048) {
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: keySize,
publicKeyEncoding: {
type: "spki",
format: "pem",
},
privateKeyEncoding: {
type: "pkcs1",
format: "pem",
},
});
fs.writeFileSync(privateKeyPath, privateKey);
fs.writeFileSync(publicKeyPath, publicKey);
console.log(`Keys generated: ${privateKeyPath}, ${publicKeyPath}`);
}
function signFile(filePath, privateKeyPath, signaturePath) {
const privateKey = fs.readFileSync(privateKeyPath, "utf8");
const data = fs.readFileSync(filePath);
const sign = crypto.createSign("SHA256");
sign.update(data);
sign.end();
const signature = sign.sign(privateKey);
fs.writeFileSync(signaturePath, signature);
console.log(`Signature written to ${signaturePath}`);
}
function verifyFile(filePath, publicKeyPath, signaturePath) {
const publicKey = fs.readFileSync(publicKeyPath, "utf8");
const data = fs.readFileSync(filePath);
const signature = fs.readFileSync(signaturePath);
const verify = crypto.createVerify("SHA256");
verify.update(data);
verify.end();
const valid = verify.verify(publicKey, signature);
console.log(`Signature is ${valid ? "VALID" : "INVALID"}.`);
return valid;
}
function demo() {
console.log("=== RSA Digital Signature Tool Demo ===\n");
const privPath = "demo_private.pem";
const pubPath = "demo_public.pem";
const demoFile = "demo_message.txt";
const sigPath = "demo_message.txt.sig";
console.log("1. Generating RSA-2048 key pair...");
generateKeys(privPath, pubPath, 2048);
fs.writeFileSync(demoFile, "This is a demo message for RSA signature verification.\n");
console.log(`\n2. Created demo file: ${demoFile}`);
console.log("\n3. Signing file...");
signFile(demoFile, privPath, sigPath);
console.log("\n4. Verifying signature...");
verifyFile(demoFile, pubPath, sigPath);
console.log("\n5. Tampering with file and verifying again...");
fs.writeFileSync(demoFile, "This message has been tampered with!\n");
verifyFile(demoFile, pubPath, sigPath);
// Cleanup
[privPath, pubPath, demoFile, sigPath].forEach((p) => {
if (fs.existsSync(p)) fs.unlinkSync(p);
});
console.log("\n6. Cleaned up demo files.");
}
function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
demo();
return;
}
const command = args[0];
function getArg(flag, defaultVal) {
const idx = args.indexOf(flag);
return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : defaultVal;
}
switch (command) {
case "keygen": {
const privKey = getArg("--private", "private.pem");
const pubKey = getArg("--public", "public.pem");
const bits = parseInt(getArg("--bits", "2048"), 10);
generateKeys(privKey, pubKey, bits);
break;
}
case "sign": {
const file = args[1];
if (!file) {
console.error("Usage: signer.js sign <file> [--key private.pem] [--output file.sig]");
process.exit(1);
}
const key = getArg("--key", "private.pem");
const output = getArg("--output", file + ".sig");
signFile(file, key, output);
break;
}
case "verify": {
const file = args[1];
if (!file) {
console.error("Usage: signer.js verify <file> [--key public.pem] [--signature file.sig]");
process.exit(1);
}
const key = getArg("--key", "public.pem");
const sig = getArg("--signature", file + ".sig");
const valid = verifyFile(file, key, sig);
process.exit(valid ? 0 : 1);
break;
}
default:
console.error(`Unknown command: ${command}`);
console.error("Usage: signer.js [keygen|sign|verify]");
process.exit(1);
}
}
main();