Get your own Node server
const crypto = require('crypto');

// Generate a key pair
const { privateKey: rsaPrivateKey, publicKey: rsaPublicKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
});

// Generate EC key pair
const { privateKey: ecPrivateKey, publicKey: ecPublicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'prime256v1',
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'sec1',
    format: 'pem'
  }
});

// Message to sign and verify
const message = 'Message to verify with different key types';

// Function to test verification with different key types
function testVerificationWithKey(publicKey, keyType, message, signature) {
  try {
    const verify = crypto.createVerify('SHA256');
    verify.update(message);
    const isValid = verify.verify(publicKey, signature, 'hex');
    
    return {
      keyType,
      isValid,
      keyFormat: typeof publicKey === 'string' ? 'PEM string' : 
                 publicKey instanceof crypto.KeyObject ? 'KeyObject' : 
                 publicKey.key ? 'Key with options' : 'Unknown'
    };
  } catch (error) {
    return {
      keyType,
      error: error.message,
      keyFormat: typeof publicKey === 'string' ? 'PEM string' : 
                 publicKey instanceof crypto.KeyObject ? 'KeyObject' : 
                 publicKey.key ? 'Key with options' : 'Unknown'
    };
  }
}

// Create a signature with RSA key
const signRSA = crypto.createSign('SHA256');
signRSA.update(message);
const rsaSignature = signRSA.sign(rsaPrivateKey, 'hex');

// Create a signature with EC key
const signEC = crypto.createSign('SHA256');
signEC.update(message);
const ecSignature = signEC.sign(ecPrivateKey, 'hex');

console.log('Message:', `"${message}"`);

// Test verification with different key types
console.log('\n1. RSA Key Verification:');
console.log(testVerificationWithKey(rsaPublicKey, 'RSA Public Key', message, rsaSignature));
console.log(testVerificationWithKey(rsaPublicKey.toString(), 'RSA Public Key as String', message, rsaSignature));
console.log(testVerificationWithKey({ key: rsaPublicKey }, 'RSA Public Key with Options', message, rsaSignature));

// Test with wrong key type (should fail)
console.log('\n2. Wrong Key Type (should fail):');
console.log(testVerificationWithKey(rsaPublicKey, 'RSA Key with EC Signature', message, ecSignature));

console.log('\n3. EC Key Verification:');
console.log(testVerificationWithKey(ecPublicKey, 'EC Public Key', message, ecSignature));
console.log(testVerificationWithKey(ecPublicKey.toString(), 'EC Public Key as String', message, ecSignature));

// Test with certificate (simulated)
try {
  console.log('\n4. Certificate Verification (simulated):');
  // In a real scenario, you would extract the public key from a certificate
  // For this example, we'll use our RSA public key directly
  const certPublicKey = {
    key: rsaPublicKey,
    format: 'pem',
    type: 'spki'
  };
  
  console.log(testVerificationWithKey(certPublicKey, 'Certificate Public Key', message, rsaSignature));
} catch (error) {
  console.log('Certificate verification error:', error.message);
}

// Test with KeyObject
console.log('\n5. KeyObject Verification:');
const keyObject = crypto.createPublicKey(rsaPublicKey);
console.log(testVerificationWithKey(keyObject, 'RSA KeyObject', message, rsaSignature));

              
Message: "Message to verify with different key types"

1. RSA Key Verification:
{ keyType: 'RSA Public Key',
  isValid: true,
  keyFormat: 'KeyObject' }
{ keyType: 'RSA Public Key as String',
  isValid: true,
  keyFormat: 'PEM string' }
{ keyType: 'RSA Public Key with Options',
  isValid: true,
  keyFormat: 'Key with options' }

2. Wrong Key Type (should fail):
{ keyType: 'RSA Key with EC Signature',
  error: 'error:04091077:rsa routines:int_rsa_verify:wrong signature length',
  keyFormat: 'KeyObject' }

3. EC Key Verification:
{ keyType: 'EC Public Key',
  isValid: true,
  keyFormat: 'KeyObject' }
{ keyType: 'EC Public Key as String',
  isValid: true,
  keyFormat: 'PEM string' }

4. Certificate Verification (simulated):
{ keyType: 'Certificate Public Key',
  isValid: true,
  keyFormat: 'Key with options' }

5. KeyObject Verification:
{ keyType: 'RSA KeyObject',
  isValid: true,
  keyFormat: 'KeyObject' }