import { generateKeyPairSync, createHash, sign, verify } from 'node:crypto';
/**
* Test suite for cryptographic functions
* Tests the core crypto functionality that will be used in the MCP server
*/
console.log('🔐 Ejecutando tests de funciones criptográficas...\n');
// Generar claves para testing
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
// Funciones auxiliares para testing
function createDataHash(data) {
const jsonString = JSON.stringify(data, null, 0);
return createHash('sha256').update(jsonString).digest('hex');
}
function signHash(hash, privateKey) {
const signature = sign('sha256', Buffer.from(hash, 'hex'), {
key: privateKey,
format: 'pem'
});
return signature.toString('base64');
}
function verifySignature(hash, signature, publicKey) {
try {
return verify(
'sha256',
Buffer.from(hash, 'hex'),
{ key: publicKey, format: 'pem' },
Buffer.from(signature, 'base64')
);
} catch (error) {
console.error('Error verificando firma:', error);
return false;
}
}
function signResponse(data) {
const hash = createDataHash(data);
const signature = signHash(hash, privateKey);
return {
data,
hash,
signature,
timestamp: new Date().toISOString(),
publicKey,
serverId: 'test-server',
version: '1.0'
};
}
function verifySignedResponse(signedResponse) {
try {
if (!signedResponse.data || !signedResponse.hash || !signedResponse.signature) {
return {
isValid: false,
error: 'Respuesta firmada incompleta',
details: { hashMatch: false, signatureValid: false }
};
}
const computedHash = createDataHash(signedResponse.data);
const hashMatch = computedHash === signedResponse.hash;
const signatureValid = verifySignature(
signedResponse.hash,
signedResponse.signature,
signedResponse.publicKey
);
return {
isValid: hashMatch && signatureValid,
error: (hashMatch && signatureValid) ? undefined : 'Hash o firma inválidos',
details: { hashMatch, signatureValid }
};
} catch (error) {
return {
isValid: false,
error: `Error durante verificación: ${error}`,
details: { hashMatch: false, signatureValid: false }
};
}
}
// Test 1: Generación y configuración de claves
console.log('Test 1: Verificar generación de claves RSA');
try {
console.log(`✅ Clave pública generada: ${publicKey.slice(0, 50)}...`);
console.log(`✅ Clave privada generada: ${privateKey.slice(0, 50)}...`);
console.log('✅ Claves RSA generadas correctamente\n');
} catch (error) {
console.error('❌ Error en Test 1:', error.message, '\n');
}
// Test 2: Creación y verificación de hash
console.log('Test 2: Verificar creación de hash SHA-256');
try {
const testData = { name: "Test User", skills: ["JavaScript", "Node.js"] };
const hash1 = createDataHash(testData);
const hash2 = createDataHash(testData);
if (hash1 !== hash2) {
throw new Error('Hashes deberían ser idénticos para los mismos datos');
}
console.log(`✅ Hash generado: ${hash1.slice(0, 16)}...`);
console.log('✅ Hashes consistentes para datos idénticos\n');
} catch (error) {
console.error('❌ Error en Test 2:', error.message, '\n');
}
// Test 3: Firma y verificación básica
console.log('Test 3: Verificar firma y verificación digital');
try {
const testData = { value: 100, status: "valid" };
const hash = createDataHash(testData);
const signature = signHash(hash, privateKey);
const isValid = verifySignature(hash, signature, publicKey);
if (!isValid) {
throw new Error('La verificación de firma falló');
}
console.log(`✅ Hash: ${hash.slice(0, 16)}...`);
console.log(`✅ Firma: ${signature.slice(0, 16)}...`);
console.log('✅ Firma y verificación funcionando correctamente\n');
} catch (error) {
console.error('❌ Error en Test 3:', error.message, '\n');
}
// Test 4: Respuesta firmada completa
console.log('Test 4: Verificar respuesta firmada completa');
try {
const testData = {
name: "Brayan Smith Cordova Tasayco",
skills: ["React", "JavaScript", "TypeScript"]
};
const signedResponse = signResponse(testData);
// Verificar que tenga todos los campos necesarios
const requiredFields = ['data', 'hash', 'signature', 'timestamp', 'publicKey', 'serverId', 'version'];
const hasAllFields = requiredFields.every(field => Object.hasOwn(signedResponse, field));
if (!hasAllFields) {
throw new Error('Respuesta firmada no tiene todos los campos requeridos');
}
console.log('✅ Respuesta firmada con todos los campos requeridos');
console.log(`✅ Timestamp: ${signedResponse.timestamp}`);
console.log(`✅ Server ID: ${signedResponse.serverId}`);
// Verificar la respuesta firmada
const verificationResult = verifySignedResponse(signedResponse);
if (!verificationResult.isValid) {
throw new Error(`Verificación falló: ${verificationResult.error}`);
}
console.log('✅ Verificación de respuesta firmada exitosa');
console.log(`✅ Hash coincide: ${verificationResult.details.hashMatch}`);
console.log(`✅ Firma válida: ${verificationResult.details.signatureValid}\n`);
} catch (error) {
console.error('❌ Error en Test 4:', error.message, '\n');
}
// Test 5: Detección de manipulación
console.log('Test 5: Verificar detección de manipulación de datos');
try {
const originalData = { value: 100, status: "valid" };
const signedResponse = signResponse(originalData);
// Manipular los datos después del firmado
const manipulatedResponse = {
...signedResponse,
data: { value: 999, status: "hacked" }
};
const verificationResult = verifySignedResponse(manipulatedResponse);
if (verificationResult.isValid) {
throw new Error('La verificación debería haber fallado para datos manipulados');
}
console.log('✅ Manipulación detectada correctamente');
console.log(`✅ Hash no coincide: ${!verificationResult.details.hashMatch}`);
console.log(`✅ Error reportado: ${verificationResult.error}\n`);
} catch (error) {
console.error('❌ Error en Test 5:', error.message, '\n');
}
// Test 6: Verificación con clave incorrecta
console.log('Test 6: Verificar rechazo con clave incorrecta');
try {
// Generar claves diferentes
const { publicKey: wrongPublicKey } = generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
const testData = { test: "data" };
const signedResponse = signResponse(testData);
// Reemplazar con clave pública incorrecta
const responseWithWrongKey = {
...signedResponse,
publicKey: wrongPublicKey
};
const verificationResult = verifySignedResponse(responseWithWrongKey);
if (verificationResult.isValid) {
throw new Error('La verificación debería haber fallado con clave incorrecta');
}
console.log('✅ Clave incorrecta rechazada correctamente');
console.log(`✅ Firma inválida detectada: ${!verificationResult.details.signatureValid}\n`);
} catch (error) {
console.error('❌ Error en Test 6:', error.message, '\n');
}
// Test 7: Performance básico
console.log('Test 7: Verificar rendimiento básico');
try {
const testData = { large: "x".repeat(1000), array: Array(100).fill("data") };
const startTime = Date.now();
const signedResponse = signResponse(testData);
const verificationResult = verifySignedResponse(signedResponse);
const endTime = Date.now();
const duration = endTime - startTime;
if (!verificationResult.isValid) {
throw new Error('Verificación falló en test de performance');
}
console.log(`✅ Firma y verificación completadas en ${duration}ms`);
console.log('✅ Rendimiento aceptable para datos grandes\n');
} catch (error) {
console.error('❌ Error en Test 7:', error.message, '\n');
}
console.log('🎉 Tests de criptografía completados!');
console.log('✨ Sistema de firma digital validado exitosamente');