Source: server/util/msSignedDataUtils.js

import crypto from 'crypto';

/**
 * Extracts the payload and the signature from raw data returned by the
 * RsaSignatureCookieTransform util.
 * See:
 * {@link https://msdn.microsoft.com/en-us/library/microsoft.identitymodel.web.rsasignaturecookietransform.aspx}
 * @param {Buffer} data The raw data to extract from
 * @returns {Object} An object containing the following properties:
 *  - {Buffer} payloadRaw The raw payload data
 *  - {string} payload The payload decoded using utf8 encoding
 *  - {Buffer} signature The signature
 */
export function extractPayloadSignature(data) {
  // read signature length
  const signatureLength = data.readInt32LE(0);
  // slice off signature
  const signature = data.slice(4, 4 + signatureLength);
  // slice off payload
  const payloadRaw = data.slice(4 + signatureLength);
  const payload = payloadRaw.toString('utf8');

  return { signature, payload, payloadRaw };
}

/**
 * Verifies a signature as generated by the RsaSignatureCookieTransform util.
 * See:
 * {@link https://msdn.microsoft.com/en-us/library/microsoft.identitymodel.web.rsasignaturecookietransform.aspx}
 *
 * @param {Buffer} payload The payload to verify
 * @param {Buffer} signature The signature to compare
 * @param {Buffer} pem The public RSA key to use when verifying the signature
 * @returns {boolean} A Boolean indicating if the signature is valid
 */
export function verifySignature(payload, signature, pem) {
  const verifier = crypto.createVerify('RSA-SHA256');
  verifier.update(payload);

  return verifier.verify(pem, signature);
}