Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SASS VUE GEN AI SCIPY CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING BASH RUST

Node.js Tutorial

Node HOME Node Intro Node Get Started Node JS Requirements Node.js vs Browser Node Cmd Line Node V8 Engine Node Architecture Node Event Loop

Asynchronous

Node Async Node Promises Node Async/Await Node Errors Handling

Module Basics

Node Modules Node ES Modules Node NPM Node package.json Node NPM Scripts Node Manage Dep Node Publish Packages

Core Modules

HTTP Module HTTPS Module File System (fs) Path Module OS Module URL Module Events Module Stream Module Buffer Module Crypto Module Timers Module DNS Module Assert Module Util Module Readline Module

JS & TS Features

Node ES6+ Node Process Node TypeScript Node Adv. TypeScript Node Lint & Formatting

Building Applications

Node Frameworks Express.js Middleware Concept REST API Design API Authentication Node.js with Frontend

Database Integration

MySQL Get Started MySQL Create Database MySQL Create Table MySQL Insert Into MySQL Select From MySQL Where MySQL Order By MySQL Delete MySQL Drop Table MySQL Update MySQL Limit MySQL Join
MongoDB Get Started MongoDB Create DB MongoDB Collection MongoDB Insert MongoDB Find MongoDB Query MongoDB Sort MongoDB Delete MongoDB Drop Collection MongoDB Update MongoDB Limit MongoDB Join

Advanced Communication

GraphQL Socket.IO WebSockets

Testing & Debugging

Node Adv. Debugging Node Testing Apps Node Test Frameworks Node Test Runner

Node.js Deployment

Node Env Variables Node Dev vs Prod Node CI/CD Node Security Node Deployment

Perfomance & Scaling

Node Logging Node Monitoring Node Performance Child Process Module Cluster Module Worker Threads

Node.js Advanced

Microservices Node WebAssembly HTTP2 Module Perf_hooks Module VM Module TLS/SSL Module Net Module Zlib Module Real-World Examples

Hardware & IoT

RasPi Get Started RasPi GPIO Introduction RasPi Blinking LED RasPi LED & Pushbutton RasPi Flowing LEDs RasPi WebSocket RasPi RGB LED WebSocket RasPi Components

Node.js Reference

Built-in Modules EventEmitter (events) Worker (cluster) Cipher (crypto) Decipher (crypto) DiffieHellman (crypto) ECDH (crypto) Hash (crypto) Hmac (crypto) Sign (crypto) Verify (crypto) Socket (dgram, net, tls) ReadStream (fs, stream) WriteStream (fs, stream) Server (http, https, net, tls) Agent (http, https) Request (http) Response (http) Message (http) Interface (readline)

Resources & Tools

Node.js Compiler Node.js Server Node.js Quiz Node.js Exercises Node.js Syllabus Node.js Study Plan Node.js Certificate

Node.js Verify Reference


Verify Object

The Verify class is part of Node.js's crypto module.

It provides a way to verify cryptographic digital signatures.

Verify instances are created using the crypto.createVerify() method.

Verify is used in conjunction with the Sign class to validate that a message was signed by a known sender and was not altered in transit.

Import Crypto Module

// Import the crypto module
const crypto = require('crypto');

// Create a Verify object
const verify = crypto.createVerify('RSA-SHA256');
Run example »

Verify Methods

Method Description
verify.update(data[, inputEncoding]) Updates the Verify content with the given data. If inputEncoding is provided, data is a string using the specified encoding; otherwise, data is a Buffer, TypedArray, or DataView. This method can be called multiple times with new data.
verify.verify(object, signature[, signatureEncoding]) Verifies the provided data using the given object and signature. object is a string containing a PEM-encoded public key, a KeyObject of type 'public', or an X.509 certificate. If signatureEncoding is provided, signature is a string using the specified encoding; otherwise it is a Buffer, TypedArray, or DataView. Returns true if the signature is valid, false otherwise.

Basic Verify Example

The following example demonstrates how to verify a digital signature of a message:

const crypto = require('crypto');
const fs = require('fs');

// Load the message, signature, and public key
// In a real application, these would typically come from files or network
// For this example, we'll try to load from the files created in the Sign example
let message, signature, publicKey;

try {
  message = fs.readFileSync('message.txt', 'utf8');
  signature = fs.readFileSync('signature.hex', 'utf8');
  publicKey = fs.readFileSync('public_key.pem', 'utf8');
} catch (error) {
  // If files don't exist, create example data
  const { privateKey, publicKey: newPublicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  });
  
  message = 'This is a message to be verified';
  publicKey = newPublicKey;
  
  // Create a signature for the example
  const sign = crypto.createSign('SHA256');
  sign.update(message);
  signature = sign.sign(privateKey, 'hex');
}

// Create a Verify object
const verify = crypto.createVerify('SHA256');

// Update with the message
verify.update(message);

// Verify the signature with the public key
const isValid = verify.verify(publicKey, signature, 'hex');

console.log('Message:', message);
console.log('Signature:', signature);
console.log('Is signature valid?', isValid);
Run example »

Verifying with Different Algorithms

The Verify class supports various signature algorithms:

const crypto = require('crypto');

// Generate key pairs for different algorithms
function generateRSAKeyPair() {
  return crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  });
}

function generateECKeyPair() {
  return crypto.generateKeyPairSync('ec', {
    namedCurve: 'prime256v1',
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'sec1',
      format: 'pem'
    }
  });
}

// Generate different key pairs
const rsaKeys = generateRSAKeyPair();
const ecKeys = generateECKeyPair();

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

// Function to sign and verify with a specific algorithm
function testSignatureVerification(algorithm, privateKey, publicKey, message) {
  try {
    // Sign the message
    const sign = crypto.createSign(algorithm);
    sign.update(message);
    const signature = sign.sign(privateKey, 'hex');
    
    // Verify the signature
    const verify = crypto.createVerify(algorithm);
    verify.update(message);
    const isValid = verify.verify(publicKey, signature, 'hex');
    
    // Try to verify with a tampered message
    const tamperedVerify = crypto.createVerify(algorithm);
    tamperedVerify.update(message + ' (tampered)');
    const isTamperedValid = tamperedVerify.verify(publicKey, signature, 'hex');
    
    return {
      algorithm,
      isValid,
      isTamperedValid
    };
  } catch (error) {
    return {
      algorithm,
      error: error.message
    };
  }
}

// Test various signature algorithms
console.log(`Message: "${message}"`);
console.log('-----------------------------------------------');

// RSA signatures with different hash algorithms
console.log('RSA Signatures:');
['SHA256', 'SHA384', 'SHA512'].forEach(hash => {
  console.log(testSignatureVerification(hash, rsaKeys.privateKey, rsaKeys.publicKey, message));
});

console.log('-----------------------------------------------');

// ECDSA signatures
console.log('ECDSA Signatures:');
['SHA256', 'SHA384'].forEach(hash => {
  console.log(testSignatureVerification(hash, ecKeys.privateKey, ecKeys.publicKey, message));
});
Run example »

Verifying with Multiple Updates

You can update a Verify object with multiple pieces of data:

const crypto = require('crypto');

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

// Create a signature with multiple updates
const sign = crypto.createSign('SHA256');
sign.update('First part of the message. ');
sign.update('Second part of the message. ');
sign.update('Third part of the message.');
const signature = sign.sign(privateKey, 'hex');

console.log('Signature created with multiple updates');

// Create a Verify object
const verify = crypto.createVerify('SHA256');

// Verify with multiple updates matching the original
verify.update('First part of the message. ');
verify.update('Second part of the message. ');
verify.update('Third part of the message.');
const isValidMultiple = verify.verify(publicKey, signature, 'hex');

console.log('Verification with matching multiple updates:', isValidMultiple);

// Verify with a single update containing the same data
const verifySingle = crypto.createVerify('SHA256');
verifySingle.update('First part of the message. Second part of the message. Third part of the message.');
const isValidSingle = verifySingle.verify(publicKey, signature, 'hex');

console.log('Verification with single update of same data:', isValidSingle);

// Try to verify with different updates
const verifyDifferent = crypto.createVerify('SHA256');
verifyDifferent.update('First part of the message. ');
verifyDifferent.update('Modified second part. ');
verifyDifferent.update('Third part of the message.');
const isValidDifferent = verifyDifferent.verify(publicKey, signature, 'hex');

console.log('Verification with different updates:', isValidDifferent);
Run example »

Verifying File Signatures

This example demonstrates verifying a digital signature for a file:

const crypto = require('crypto');
const fs = require('fs');

// Function to verify a file's signature
function verifyFile(filePath, signaturePath, publicKey, algorithm = 'SHA256') {
  return new Promise((resolve, reject) => {
    try {
      // Read the signature
      const signature = fs.readFileSync(signaturePath, 'utf8');
      
      // Create Verify object
      const verify = crypto.createVerify(algorithm);
      
      // Create read stream for the file
      const readStream = fs.createReadStream(filePath);
      
      // Handle stream events
      readStream.on('data', (data) => {
        verify.update(data);
      });
      
      readStream.on('end', () => {
        // Verify the signature
        const isValid = verify.verify(publicKey, signature, 'hex');
        resolve(isValid);
      });
      
      readStream.on('error', (error) => {
        reject(error);
      });
    } catch (error) {
      reject(error);
    }
  });
}

// For this example, create a file, sign it, and verify it
const filePath = 'example_to_verify.txt';
const signaturePath = `${filePath}.sig`;
const publicKeyPath = 'verify_public_key.pem';

// Create a test environment if files don't exist
if (!fs.existsSync(filePath) || !fs.existsSync(signaturePath) || !fs.existsSync(publicKeyPath)) {
  console.log('Creating test environment...');
  
  // Generate a keypair
  const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  });
  
  // Save the public key
  fs.writeFileSync(publicKeyPath, publicKey);
  
  // Create a test file
  fs.writeFileSync(filePath, 'This is a test file for signature verification.\n'.repeat(100));
  
  // Sign the file
  const sign = crypto.createSign('SHA256');
  const fileContent = fs.readFileSync(filePath);
  sign.update(fileContent);
  const signature = sign.sign(privateKey, 'hex');
  
  // Save the signature
  fs.writeFileSync(signaturePath, signature);
  
  console.log('Test environment created');
}

// Load the public key
const publicKey = fs.readFileSync(publicKeyPath, 'utf8');

// Verify the file signature
verifyFile(filePath, signaturePath, publicKey)
  .then(isValid => {
    console.log(`File: ${filePath}`);
    console.log(`Signature: ${signaturePath}`);
    console.log(`Verification result: ${isValid ? 'Valid signature' : 'Invalid signature'}`);
    
    // Demonstrate a tampered file
    if (isValid) {
      const tamperedFilePath = `${filePath}.tampered`;
      fs.copyFileSync(filePath, tamperedFilePath);
      
      // Make a small change to the file
      const content = fs.readFileSync(tamperedFilePath, 'utf8');
      fs.writeFileSync(tamperedFilePath, content.replace('verification', 'TAMPERED'));
      
      // Verify the tampered file with the original signature
      return verifyFile(tamperedFilePath, signaturePath, publicKey)
        .then(isTamperedValid => {
          console.log(`\nTampered file: ${tamperedFilePath}`);
          console.log(`Verification result: ${isTamperedValid ? 'Valid signature (unexpected!)' : 'Invalid signature (expected)'}`);
        });
    }
  })
  .catch(error => {
    console.error('Error verifying file:', error.message);
  });
Run example »

Verifying with Different Key Types

The Verify class can work with different formats of public keys:

const crypto = require('crypto');
const fs = require('fs');

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

// Function to sign and verify with different key formats
function verifyWithKeyFormat(publicKey, keyFormat, algorithm = 'SHA256') {
  try {
    // Generate keypair for test
    const { privateKey, publicKey: generatedPublicKey } = crypto.generateKeyPairSync('rsa', {
      modulusLength: 2048,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem'
      }
    });
    
    // Sign the message with private key
    const sign = crypto.createSign(algorithm);
    sign.update(message);
    const signature = sign.sign(privateKey, 'hex');
    
    // Verify with the provided public key format
    const verify = crypto.createVerify(algorithm);
    verify.update(message);
    return {
      format: keyFormat,
      isValid: verify.verify(publicKey, signature, 'hex')
    };
  } catch (error) {
    return {
      format: keyFormat,
      error: error.message
    };
  }
}

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

// Sign the message for verification tests
const sign = crypto.createSign('SHA256');
sign.update(message);
const signature = sign.sign(privateKey, 'hex');

// Function to verify with different key formats
function testVerifyWithKey(publicKey, keyFormat) {
  try {
    const verify = crypto.createVerify('SHA256');
    verify.update(message);
    return {
      format: keyFormat,
      isValid: verify.verify(publicKey, signature, 'hex')
    };
  } catch (error) {
    return {
      format: keyFormat,
      error: error.message
    };
  }
}

console.log(`Message: "${message}"`);
console.log('Signature:', signature.substring(0, 32) + '...');

// 1. Verify with PEM-encoded public key (string)
console.log('\n1. PEM-encoded public key (string):');
console.log(testVerifyWithKey(pemPublicKey, 'PEM string'));

// 2. Verify with PEM-encoded public key (buffer)
console.log('\n2. PEM-encoded public key (buffer):');
console.log(testVerifyWithKey(Buffer.from(pemPublicKey), 'PEM buffer'));

// 3. Verify with KeyObject
console.log('\n3. KeyObject:');
const keyObject = crypto.createPublicKey(pemPublicKey);
console.log(testVerifyWithKey(keyObject, 'KeyObject'));

// 4. Try to verify with X.509 certificate
console.log('\n4. X.509 Certificate (simulated):');
console.log({
  format: 'X.509 Certificate',
  note: 'In a real scenario, you would load an X.509 certificate containing the public key'
});

// 5. Try to verify with JWK (requires conversion)
console.log('\n5. JWK (requires conversion):');
console.log({
  format: 'JWK',
  note: 'JWK needs to be converted to PEM or KeyObject first'
});
Run example »

Verifying with Advanced Options

Verifying signatures with specific OpenSSL options:

const crypto = require('crypto');

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

// Message to sign
const message = 'Message to verify with different options';

// Function to sign with specific options
function signWithOptions(algorithm, message, privateKey, options = {}) {
  // Create private key with options
  const keyWithOptions = {
    key: privateKey,
    ...options
  };
  
  // Sign the message
  const sign = crypto.createSign(algorithm);
  sign.update(message);
  return sign.sign(keyWithOptions, 'hex');
}

// Function to verify with specific options
function verifyWithOptions(algorithm, message, publicKey, signature, options = {}) {
  try {
    // Create public key with options
    const keyWithOptions = {
      key: publicKey,
      ...options
    };
    
    // Verify the signature
    const verify = crypto.createVerify(algorithm);
    verify.update(message);
    return verify.verify(keyWithOptions, signature, 'hex');
  } catch (error) {
    return `Error: ${error.message}`;
  }
}

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

// 1. Sign and verify with standard PKCS#1 v1.5 padding (default)
const sig1 = signWithOptions('SHA256', message, privateKey);
console.log('\n1. Standard PKCS#1 v1.5 padding:');
console.log('Signature:', sig1.substring(0, 32) + '...');
console.log('Verification result:', verifyWithOptions('SHA256', message, publicKey, sig1));

// 2. Sign and verify with PSS padding
const pssOptions = {
  padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
  saltLength: 32
};
const sig2 = signWithOptions('SHA256', message, privateKey, pssOptions);
console.log('\n2. PSS padding:');
console.log('Signature:', sig2.substring(0, 32) + '...');
console.log('Verification result (matching options):',
  verifyWithOptions('SHA256', message, publicKey, sig2, pssOptions));
console.log('Verification result (default options):',
  verifyWithOptions('SHA256', message, publicKey, sig2));

// 3. Verify with PSS padding and different salt lengths
console.log('\n3. PSS padding with different salt lengths:');
[20, 32, 48].forEach(saltLength => {
  const sigSalt = signWithOptions('SHA256', message, privateKey, {
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
    saltLength
  });
  
  console.log(`Salt length ${saltLength}:`);
  
  // Try to verify with correct salt length
  console.log(`  - Verify with correct salt length (${saltLength}):`,
    verifyWithOptions('SHA256', message, publicKey, sigSalt, {
      padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
      saltLength
    }));
  
  // Try to verify with wrong salt length
  const wrongSaltLength = saltLength + 10;
  console.log(`  - Verify with wrong salt length (${wrongSaltLength}):`,
    verifyWithOptions('SHA256', message, publicKey, sigSalt, {
      padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
      saltLength: wrongSaltLength
    }));
});
Run example »

Certificate-Based Verification

Verifying signatures using X.509 certificates:

const crypto = require('crypto');
const fs = require('fs');

// Function to simulate a certificate-based verification
function demonstrateCertificateVerification() {
  console.log('Certificate-Based Verification Demonstration');
  console.log('-------------------------------------------');
  
  console.log('In a real application, you would:');
  console.log('1. Obtain an X.509 certificate containing the signer\'s public key');
  console.log('2. Verify the certificate\'s trust chain');
  console.log('3. Extract the public key from the certificate');
  console.log('4. Use that public key to verify the signature');
  
  console.log('\nSimplified example:');
  
  // Generate a key pair
  const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  });
  
  // In a real app, you'd have a certificate with the public key
  const mockCertificate = `-----BEGIN CERTIFICATE-----
(This would be a real X.509 certificate containing the public key)
-----END CERTIFICATE-----`;
  
  // Message to sign
  const message = 'Message signed with a certificate-backed key';
  
  // Sign the message
  const sign = crypto.createSign('SHA256');
  sign.update(message);
  const signature = sign.sign(privateKey, 'hex');
  
  console.log(`Message: "${message}"`);
  console.log(`Signature: ${signature.substring(0, 32)}...`);
  
  console.log('\nVerification steps:');
  console.log('1. Extract public key from certificate (simulated)');
  
  // In a real scenario, you'd extract the public key from the certificate
  // For this example, we'll use our generated public key directly
  console.log('2. Verify the signature using the extracted public key');
  
  const verify = crypto.createVerify('SHA256');
  verify.update(message);
  const isValid = verify.verify(publicKey, signature, 'hex');
  
  console.log(`Verification result: ${isValid ? 'Valid signature' : 'Invalid signature'}`);
}

// Run the demonstration
demonstrateCertificateVerification();
Run example »

Security Best Practices

When verifying digital signatures, consider these security best practices:

  1. Trust management: Validate the source of the public key used for verification. Don't trust a public key unless it comes from a trusted source.
  2. Certificate validation: When using certificates, verify the entire certificate chain and check certificate revocation status.
  3. Matching signing algorithm: Ensure the verification algorithm matches the signing algorithm, including any options like padding or salt length.
  4. Input validation: Validate and sanitize any data before verification to prevent injection attacks.
  5. Fail securely: Always default to rejecting signatures that fail verification for any reason.
  6. Keep verification code simple: Complexity increases the risk of verification bypass vulnerabilities.
  7. Consider timing attacks: Signature verification may be vulnerable to timing attacks in some implementations.

Common Use Cases for Signature Verification

  • Software Updates: Verifying the authenticity of updates before installation.
  • Document Verification: Ensuring digitally signed documents haven't been modified.
  • API Authentication: Verifying the identity of API requests.
  • JWT Validation: Verifying JSON Web Token signatures.
  • Certificate Chain Validation: Verifying signatures in a certificate chain.
  • Secure Communication: Authenticating messages in secure protocols.

×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
sales@w3schools.com

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
help@w3schools.com

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2025 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.