title: Node.js: Signature verification (PS256) succeeds in Node.js but fails in jwt.io debugger
body: <p>I wrote a test script with which I'm signing and then verifying a JWT with the PS256 algorithm.</p>
  
  <p>My code verifies the JWT successfully, but the verification fails in the <a href="https://jwt.io" rel="nofollow noreferrer">jwt.io</a> debugger.</p>
  
  <p>I'm using <code>jws@3.2.1</code>.</p>
  
  <p><strong>This happens only when using the PS256 algorithm, not when using, for instance, RS256.</strong></p>
  
  <p>Am I doing anything wrong?</p>
  
  <p>I generated my keys with:</p>
  
  <pre class="lang-sh prettyprint-override"><code>openssl genpkey -algorithm RSA -out private_key2.pem -pkeyopt rsa_keygen_bits:2048
  openssl rsa -pubout -in private_key2.pem -out public_key2.pem
  </code></pre>
  
  <p>You can try my code on repl.it: <a href="https://repl.it/@SamArtuso/Nodejs-Signature-verification-PS256-succeeds-in-Nodejs" rel="nofollow noreferrer">https://repl.it/@SamArtuso/Nodejs-Signature-verification-PS256-succeeds-in-Nodejs</a></p>
  
  <p>Code:</p>
  
  <pre class="lang-js prettyprint-override"><code>const { join } = require('path');
  const { readFileSync } = require('fs');
  const jws = require('jws');
  
  const ALG = 'PS256';
  
  /**********
   * SIGNING
   **********/
  
  const PRIVATE_KEY_PATH = join(__dirname, './keys/private_key2.pem');
  
  const privateKey = readFileSync(PRIVATE_KEY_PATH).toString();
  
  const payload = {
    foo: 'bar',
  };
  
  const token = jws.sign({
    header: { alg: ALG },
    payload,
    privateKey,
  })
  
  console.log('Token:');
  console.log(token);
  
  /************
   * VERIFYING
   ************/
  
  const PUBLIC_KEY_PATH = join(__dirname, './keys/public_key2.pem');
  
  const publicKey = readFileSync(PUBLIC_KEY_PATH).toString();
  
  const result = jws.verify(token, ALG, publicKey);
  if (result) {
    console.log('Verification successful.');
  } else {
    console.error('Verification failed.');
  }
  </code></pre>
  
  <p>Private key:</p>
  
  <pre><code>-----BEGIN PRIVATE KEY-----
  MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPR8CD/9V9fddR
  vMk590JtuU4hPT9iPD/mYeWdvUTbkN2iPpg6LDADBntz8I9CzThCkgHmDQhh49Qz
  AONiHfyHhKT6HHIBS78wGWfhE9ueFtkv19xisvFJTDO6IllGFMiioj8AkvOJwaY+
  5ZKSFG32V0gMaglNSNTOh5KK6DsxgdH2KfMzn6uFwJkvsz1qwPiINu/rqvOQPOIK
  JCbNHBOg/SvhPWBSEFDC9AkLm3ajhGAcnSlWi0KgUFz7iHuUR6s4GLdkc40uAooY
  ExEWsZyoByT18tXln2hPAvE1Ata2PSbtLHuwvMQt4vzZi80K4BXqOiqvNMo1A1aT
  oSQnmOwtAgMBAAECggEAPpHTPEVS5aHCCItrVtMbu1FvkzsQ0g+L3nh4vqfujDTr
  olkwzIagK5meVH4uUKTwMbAvYIlYmWwTlx3ShcC1hRb2UgWaKGf8G4HfyKKc7djJ
  0NZhUW3gxhZ5mttZhX0qn2VIjVzOpSvOijf0iaIfG3h3aD/t9OViT8G+6610iNmz
  Oygmi9kQaBAS2A2sLSSMhdyddIPEpZ8QOHwGCRvBXWO100BCV9ROQzYxW+U9VPaJ
  I0tXDL1L1H7y1EbxccPfOsfUPMtF9LQWQZ6ksJuSRwkBAnfKpzexguph29sLDjCQ
  X23rQN/NwiU+zRmn+cW7VqkZsbSqucP9t+d19UdWpQKBgQDn9sThxAZvx4OS0noD
  AWJX5CliDNlagmLqr4c0QoYI+fPL7FcK9tQYUZ869jnebX7UPHTuDhMoIvWknZbB
  QhoogpRoX+XFtxzPwjtBBGc5TYacYnOR4xPSjvDlIrY7FQiH8TgpAGzenSBiD8O0
  xW4zSaHLUDHEMFEyPq8tdMmBewKBgQDkwjUnVMPlA9AOD+KQNXgf2kV9z0ZA5idt
  9WcsXsxpO2W6S0ntkr29Yr3VuuuJTRH7Fm+bPDJ6C1bfZ746hn3iLMZbMxgGVEf/
  cN0nNXjfG5G7EEIU9WFges1I5rec/5W38kIco6soP36Qj5HcUBXt6AHy3k1IbEL2
  84Bp1SZ0dwKBgF19mhCcXzPCKAePCVoYvrhJ31wDbb8K+i84m7e2cCtCAr7X/KUQ
  op9Clni/MMezPgDwdPhVd+cfX/3+/fnaWIynRIVk0UkE6nnaAOPNkIUJ+A0jqQzN
  hvnAXtsbSHM7oPqZgFcWMsrubVTYobpEMIw/SxSUt9oo1zD3Dse1YFntAoGBAIAL
  AIuKU7f9gVhNpehINXvGxfzcpxsueEWBBgX87fe9CnzTJYc4CsJV4aIfZTVOEVF0
  xnWipTJQ5IhZ3k2N+CpAG6ryl3D7fe1J9E+9C3H+UXzeZc6rZp0FP6Cdm4riOKBk
  loLHTcdSevpZkjA6F3w5z9Vsft+Z0YW+2FLkvwiTAoGAdjUYcGTaEhGNtHQszAeY
  2VbeVHwgnajKhaZpKMNTVp/AFgeS5k1lSATlT5wQHD3OAhUn+NAEwUOUBBWOpg+i
  jML8loplEcVmdHkfGFsrIvzFFIIXQOWy77s/McTCh2jLkLYO8kIOrGy08JBiZnQ/
  Ki/HFS/2yaUbG6UdH8FFp2g=
  -----END PRIVATE KEY-----
  </code></pre>
  
  <p>Public key:</p>
  
  <pre><code>-----BEGIN PUBLIC KEY-----
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz0fAg//VfX3XUbzJOfdC
  bblOIT0/Yjw/5mHlnb1E25Ddoj6YOiwwAwZ7c/CPQs04QpIB5g0IYePUMwDjYh38
  h4Sk+hxyAUu/MBln4RPbnhbZL9fcYrLxSUwzuiJZRhTIoqI/AJLzicGmPuWSkhRt
  9ldIDGoJTUjUzoeSiug7MYHR9inzM5+rhcCZL7M9asD4iDbv66rzkDziCiQmzRwT
  oP0r4T1gUhBQwvQJC5t2o4RgHJ0pVotCoFBc+4h7lEerOBi3ZHONLgKKGBMRFrGc
  qAck9fLV5Z9oTwLxNQLWtj0m7Sx7sLzELeL82YvNCuAV6joqrzTKNQNWk6EkJ5js
  LQIDAQAB
  -----END PUBLIC KEY-----
  </code></pre>
  
  <p><strong>Edit:</strong> Clarifications on how to reproduce my issue.</p>
  
  <ol>
  <li>Run my script with: <code>npm init -f &amp;&amp; npm install jws &amp;&amp; node test.js</code></li>
  <li>The script will output the token and <code>Verification successful.</code></li>
  <li>Copy and paste the token in the "Encoded" field on jwt.io</li>
  <li>Copy and paste the public key in the "Public key or certificate" field.</li>
  <li>A red "Invalid Signature" message appears at the bottom.</li>
  </ol>
  
  <p>The below is an example of the token my script will generate. Bear in mind that PS256 has a <em>probabilistic</em> rather than <em>deterministic</em> signature, so the signature will be different every time you run the script.</p>
  
  <pre><code>eyJhbGciOiJQUzI1NiJ9.eyJmb28iOiJiYXIifQ.Rn6i-94ovuKOVRc2jzLVS40MpMmBkIfkyvF56JK3tM8wvg-DW943NNbXf01bhRdyoUj0A73NSQtz0kB4WfXN1uAH1omzNr0ww-iTfC23AX0OcjbsE7CcDz_ZQWWOzwEGGFVfV9ez5yn1pKRYVdFaKqApk3irP-ej_WGrrJfgeZVs683lNk0WjKOYhj6vsryuz52c0OEJ0UmYy7hSSfL38jgL6bdE0awg2DgiaU6qszZEkMjSnugoMobeAUUyOiXHsR79NryuhCQko-I9P1vKd1dEA3zM1iut5sW5FwB8K9Fi49gaQy0zHk72txJvUWdxW5ns0Svft3qLke5XMuqm2g
  </code></pre>