Sling Academy
Home/JavaScript/Sign and Verify Messages via the Web Crypto API in JavaScript

Sign and Verify Messages via the Web Crypto API in JavaScript

Last updated: December 13, 2024

The Web Crypto API is a powerful tool in modern web development that provides an interface for performing cryptographic operations in a secure manner. This API is available to anyone using a modern browser and allows for a wide array of cryptographic activities, like generating random numbers, encrypting and decrypting data, and, importantly for our article, signing and verifying messages.

What Are Message Signing and Verification?

Message signing is the process of appending a cryptographic signature to a message that proves the identity of the signer and guarantees the authenticity of the message content. Verification ensures that the signature attached to the message is valid and that the message hasn’t been tampered with.

Getting Started with the Web Crypto API

Before delving into signing and verification, you need to ensure your environment supports the Web Crypto API. This is available in most up-to-date browsers, so generally, no setup is required beyond writing some JavaScript.

Let's start with a fundamental example of generating cryptographic keys, which we'll use for signing and verifying messages.

// Generate an asymmetric key pair
async function generateKeyPair() {
  const keyPair = await window.crypto.subtle.generateKey(
    {
      name: 'RSASSA-PKCS1-v1_5',
      modulusLength: 2048,
      publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
      hash: 'SHA-256'
    },
    true,
    ['sign', 'verify']
  );
  return keyPair;
}

// Usage
(async () => {
  const keyPair = await generateKeyPair();
  console.log(keyPair);
})();

Signing a Message

Once you have your key pair, signing a message is straightforward. You'll use the private key from your key pair to create the signature.

async function signMessage(message, privateKey) {
  const enc = new TextEncoder();
  const encodedMessage = enc.encode(message);
  return await window.crypto.subtle.sign(
    {
      name: 'RSASSA-PKCS1-v1_5'
    },
    privateKey,
    encodedMessage
  );
}

// Usage
(async () => {
  const keyPair = await generateKeyPair();
  const signature = await signMessage('Hello, World!', keyPair.privateKey);
  console.log(new Uint8Array(signature));
})();

Verifying a Message

Verifying involves checking the signature using the associated public key. If verification is successful, the operation confirms that the message was signed by the private key holder and the content was not altered.

async function verifyMessage(message, signature, publicKey) {
  const enc = new TextEncoder();
  const encodedMessage = enc.encode(message);
  return await window.crypto.subtle.verify(
    {
      name: 'RSASSA-PKCS1-v1_5'
    },
    publicKey,
    signature,
    encodedMessage
  );
}

// Usage
(async () => {
  const keyPair = await generateKeyPair();
  const message = 'Hello, World!';
  const signature = await signMessage(message, keyPair.privateKey);
  const isValid = await verifyMessage(message, signature, keyPair.publicKey);
  console.log('Signature valid:', isValid);
})();

Handling Errors and Edge Cases

When working with cryptographic operations, consider handling errors and unexpected inputs to maintain the integrity and reliability of your application. Common issues may include:

  • Invalid key parameters during key generation.
  • Incorrect message encoding or decoding processes.
  • Mismatched key types for signing and verification.

Error handling can be achieved using try-catch blocks to intercept exceptions and log them appropriately:

try {
  const keyPair = await generateKeyPair();
  // Carry out signing and verification
} catch (error) {
  console.error('An error occurred:', error);
}

Conclusion

The Web Crypto API is a useful tool for securing communications in web applications through client-side cryptography. Mastering the aspects of message signing and verification can significantly enhance the security of data exchange, verifying the authenticity of the messages and safeguarding against tampering.

As with every powerful tool, make sure to stay informed about the latest updates in the Web Crypto API and best practices surrounding cryptographic security.

Next Article: Implement Secure Hashing and Random Values in JavaScript Web Crypto

Previous Article: Ensure Secure Communications Using JavaScript Web Crypto

Series: Web APIs – JavaScript Tutorials

JavaScript

You May Also Like

  • Handle Zoom and Scroll with the Visual Viewport API in JavaScript
  • Improve Security Posture Using JavaScript Trusted Types
  • Allow Seamless Device Switching Using JavaScript Remote Playback
  • Update Content Proactively with the JavaScript Push API
  • Simplify Tooltip and Dropdown Creation via JavaScript Popover API
  • Improve User Experience Through Performance Metrics in JavaScript
  • Coordinate Workers Using Channel Messaging in JavaScript
  • Exchange Data Between Iframes Using Channel Messaging in JavaScript
  • Manipulating Time Zones in JavaScript Without Libraries
  • Solving Simple Algebraic Equations Using JavaScript Math Functions
  • Emulating Traditional OOP Constructs with JavaScript Classes
  • Smoothing Out User Flows: Focus Management Techniques in JavaScript
  • Creating Dynamic Timers and Counters with JavaScript
  • Implement Old-School Data Fetching Using JavaScript XMLHttpRequest
  • Load Dynamic Content Without Reloading via XMLHttpRequest in JavaScript
  • Manage Error Handling and Timeouts Using XMLHttpRequest in JavaScript
  • Handle XML and JSON Responses via JavaScript XMLHttpRequest
  • Make AJAX Requests with XMLHttpRequest in JavaScript
  • Customize Subtitle Styling Using JavaScript WebVTT Integration