I have a file with a signature, how do I verify the content matches the signature + public key on the client?

Viewed 191

I am trying to do client-side validation of the contents of a file but am not very familiar with web crypto and am struggling to make progress.

Currently I am facing the an error saying:

Cannot create a key using the specified key usages.

Here is a sandbox URL with the below example

Using the SubjectPublicKeyInfo instructions on the Subtle Crypto documentation.

I have the following javascript

void async function main() {
  const [ contentBytes, signatureBase64, publicKeyString ] = await Promise.all([
    (await fetch('./file.js')).arrayBuffer(),
    (await fetch('./file.js.signature.b64')).text(),
    (await fetch('./keys/rsa_public.pem')).text(),
  ])

  const publicKeyBytes = await importRsaKey(publicKeyString)
  await crypto.subtle.verify('RSA-SHA256', publicKeyBytes, signatureBase64, contentBytes)
}()

My implementation for the importRsaKey function is

function str2ab(str) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

function importRsaKey(pem) {
  const pemContents = pem.trim().split('\n').
    filter(v => !v.includes('--')).join('')
  const binaryDerString = window.atob(pemContents);
  const binaryDer = str2ab(binaryDerString);

  return window.crypto.subtle.importKey(
    "spki",
    binaryDer,
    {
      name: "RSA-OAEP",
      hash: "SHA-256"
    },
    true,
    ['verify']
  );
}

I generated the public/private keys and signature using:

openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

openssl dgst -sha256 -sign "./rsa_private.pem" -out file.js.signature file.js
base64 file.js.signature > file.js.signature.b64
0 Answers
Related