How to verify the signed message against the signature with raw ec public key only #4447

Description

@chlin501

Node.js Version

v20.14.0

NPM Version

v9.2.0

Operating System

Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

Subsystem

crypto

Description

I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

const gen = createECDH('prime256v1');
gen.generateKeys();
return { publicKey: gen.getPublicKey('base64'),
privateKey: gen.getPrivateKey('base64')
};

And the way to sign is done by

const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
const signer = createSign('SHA256')
signer.update(message); // the message is a string
signer.end();
signer.sign(privatekey, 'base64'); 

Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

I attempted to create a public key only pem string as below

function convert_raw_ec_key(raw_key) {
return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
}
const pemstr = `-----BEGIN PUBLIC KEY-----
${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
-----END PUBLIC KEY-----`;
const myv = createVerify('SHA256');
myv.update(message);// the message is a string
myv.end();
const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
assert(true === result); // but this fails because result is false

Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

Many thanks.

Minimal Reproduction

  1. Sign
    1. Create the pem string from the private key and public key
    2. Pass the pem string to createPrivateKey({key: pem})
    3. sign the message with createSign(), update(), end(), then sign() for generating signature
  2. Verify
    1. Create the pem string from the public key
    2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

Output

const result = verify.verify(pem, Buffer.from(signature, 'base64'));
console.log(result );
assert(true === result);
console show the result is false, and assert also fail as the result is false.

Before You Submit

  • I have looked for issues that already exist before submitting this
  • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
      Skip to content

      How to verify the signed message against the signature with raw ec public key only #4447

      Description

      @chlin501

      Node.js Version

      v20.14.0

      NPM Version

      v9.2.0

      Operating System

      Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

      Subsystem

      crypto

      Description

      I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

      const gen = createECDH('prime256v1');
      gen.generateKeys();
      return { publicKey: gen.getPublicKey('base64'),
      privateKey: gen.getPrivateKey('base64')
      };
      

      And the way to sign is done by

      const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
      const signer = createSign('SHA256')
      signer.update(message); // the message is a string
      signer.end();
      signer.sign(privatekey, 'base64'); 

      Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

      I attempted to create a public key only pem string as below

      function convert_raw_ec_key(raw_key) {
      return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
      }
      const pemstr = `-----BEGIN PUBLIC KEY-----
      ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
      -----END PUBLIC KEY-----`;
      const myv = createVerify('SHA256');
      myv.update(message);// the message is a string
      myv.end();
      const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
      assert(true === result); // but this fails because result is false
      

      Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

      Many thanks.

      Minimal Reproduction

      1. Sign
        1. Create the pem string from the private key and public key
        2. Pass the pem string to createPrivateKey({key: pem})
        3. sign the message with createSign(), update(), end(), then sign() for generating signature
      2. Verify
        1. Create the pem string from the public key
        2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

      Output

      const result = verify.verify(pem, Buffer.from(signature, 'base64'));
      console.log(result );
      assert(true === result);
      console show the result is false, and assert also fail as the result is false.

      Before You Submit

      • I have looked for issues that already exist before submitting this
      • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Assignees

      No one assigned

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
          Skip to content

          How to verify the signed message against the signature with raw ec public key only #4447

          Description

          @chlin501

          Node.js Version

          v20.14.0

          NPM Version

          v9.2.0

          Operating System

          Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

          Subsystem

          crypto

          Description

          I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

          const gen = createECDH('prime256v1');
          gen.generateKeys();
          return { publicKey: gen.getPublicKey('base64'),
          privateKey: gen.getPrivateKey('base64')
          };
          

          And the way to sign is done by

          const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
          const signer = createSign('SHA256')
          signer.update(message); // the message is a string
          signer.end();
          signer.sign(privatekey, 'base64'); 

          Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

          I attempted to create a public key only pem string as below

          function convert_raw_ec_key(raw_key) {
          return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
          }
          const pemstr = `-----BEGIN PUBLIC KEY-----
          ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
          -----END PUBLIC KEY-----`;
          const myv = createVerify('SHA256');
          myv.update(message);// the message is a string
          myv.end();
          const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
          assert(true === result); // but this fails because result is false
          

          Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

          Many thanks.

          Minimal Reproduction

          1. Sign
            1. Create the pem string from the private key and public key
            2. Pass the pem string to createPrivateKey({key: pem})
            3. sign the message with createSign(), update(), end(), then sign() for generating signature
          2. Verify
            1. Create the pem string from the public key
            2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

          Output

          const result = verify.verify(pem, Buffer.from(signature, 'base64'));
          console.log(result );
          assert(true === result);
          console show the result is false, and assert also fail as the result is false.

          Before You Submit

          • I have looked for issues that already exist before submitting this
          • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Assignees

          No one assigned

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              How to verify the signed message against the signature with raw ec public key only #4447

              Description

              @chlin501

              Node.js Version

              v20.14.0

              NPM Version

              v9.2.0

              Operating System

              Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

              Subsystem

              crypto

              Description

              I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

              const gen = createECDH('prime256v1');
              gen.generateKeys();
              return { publicKey: gen.getPublicKey('base64'),
              privateKey: gen.getPrivateKey('base64')
              };
              

              And the way to sign is done by

              const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
              const signer = createSign('SHA256')
              signer.update(message); // the message is a string
              signer.end();
              signer.sign(privatekey, 'base64'); 

              Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

              I attempted to create a public key only pem string as below

              function convert_raw_ec_key(raw_key) {
              return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
              }
              const pemstr = `-----BEGIN PUBLIC KEY-----
              ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
              -----END PUBLIC KEY-----`;
              const myv = createVerify('SHA256');
              myv.update(message);// the message is a string
              myv.end();
              const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
              assert(true === result); // but this fails because result is false
              

              Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

              Many thanks.

              Minimal Reproduction

              1. Sign
                1. Create the pem string from the private key and public key
                2. Pass the pem string to createPrivateKey({key: pem})
                3. sign the message with createSign(), update(), end(), then sign() for generating signature
              2. Verify
                1. Create the pem string from the public key
                2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

              Output

              const result = verify.verify(pem, Buffer.from(signature, 'base64'));
              console.log(result );
              assert(true === result);
              console show the result is false, and assert also fail as the result is false.

              Before You Submit

              • I have looked for issues that already exist before submitting this
              • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Assignees

              No one assigned

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
                  Skip to content

                  How to verify the signed message against the signature with raw ec public key only #4447

                  Description

                  @chlin501

                  Node.js Version

                  v20.14.0

                  NPM Version

                  v9.2.0

                  Operating System

                  Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

                  Subsystem

                  crypto

                  Description

                  I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

                  const gen = createECDH('prime256v1');
                  gen.generateKeys();
                  return { publicKey: gen.getPublicKey('base64'),
                  privateKey: gen.getPrivateKey('base64')
                  };
                  

                  And the way to sign is done by

                  const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
                  const signer = createSign('SHA256')
                  signer.update(message); // the message is a string
                  signer.end();
                  signer.sign(privatekey, 'base64'); 

                  Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

                  I attempted to create a public key only pem string as below

                  function convert_raw_ec_key(raw_key) {
                  return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
                  }
                  const pemstr = `-----BEGIN PUBLIC KEY-----
                  ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
                  -----END PUBLIC KEY-----`;
                  const myv = createVerify('SHA256');
                  myv.update(message);// the message is a string
                  myv.end();
                  const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
                  assert(true === result); // but this fails because result is false
                  

                  Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

                  Many thanks.

                  Minimal Reproduction

                  1. Sign
                    1. Create the pem string from the private key and public key
                    2. Pass the pem string to createPrivateKey({key: pem})
                    3. sign the message with createSign(), update(), end(), then sign() for generating signature
                  2. Verify
                    1. Create the pem string from the public key
                    2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

                  Output

                  const result = verify.verify(pem, Buffer.from(signature, 'base64'));
                  console.log(result );
                  assert(true === result);
                  console show the result is false, and assert also fail as the result is false.

                  Before You Submit

                  • I have looked for issues that already exist before submitting this
                  • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

                  Activity

                  Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                      Skip to content

                      How to verify the signed message against the signature with raw ec public key only #4447

                      Description

                      @chlin501

                      Node.js Version

                      v20.14.0

                      NPM Version

                      v9.2.0

                      Operating System

                      Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

                      Subsystem

                      crypto

                      Description

                      I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

                      const gen = createECDH('prime256v1');
                      gen.generateKeys();
                      return { publicKey: gen.getPublicKey('base64'),
                      privateKey: gen.getPrivateKey('base64')
                      };
                      

                      And the way to sign is done by

                      const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
                      const signer = createSign('SHA256')
                      signer.update(message); // the message is a string
                      signer.end();
                      signer.sign(privatekey, 'base64'); 

                      Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

                      I attempted to create a public key only pem string as below

                      function convert_raw_ec_key(raw_key) {
                      return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
                      }
                      const pemstr = `-----BEGIN PUBLIC KEY-----
                      ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
                      -----END PUBLIC KEY-----`;
                      const myv = createVerify('SHA256');
                      myv.update(message);// the message is a string
                      myv.end();
                      const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
                      assert(true === result); // but this fails because result is false
                      

                      Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

                      Many thanks.

                      Minimal Reproduction

                      1. Sign
                        1. Create the pem string from the private key and public key
                        2. Pass the pem string to createPrivateKey({key: pem})
                        3. sign the message with createSign(), update(), end(), then sign() for generating signature
                      2. Verify
                        1. Create the pem string from the public key
                        2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

                      Output

                      const result = verify.verify(pem, Buffer.from(signature, 'base64'));
                      console.log(result );
                      assert(true === result);
                      console show the result is false, and assert also fail as the result is false.

                      Before You Submit

                      • I have looked for issues that already exist before submitting this
                      • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

                      Activity

                      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                          Skip to content

                          How to verify the signed message against the signature with raw ec public key only #4447

                          Description

                          @chlin501

                          Node.js Version

                          v20.14.0

                          NPM Version

                          v9.2.0

                          Operating System

                          Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

                          Subsystem

                          crypto

                          Description

                          I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

                          const gen = createECDH('prime256v1');
                          gen.generateKeys();
                          return { publicKey: gen.getPublicKey('base64'),
                          privateKey: gen.getPrivateKey('base64')
                          };
                          

                          And the way to sign is done by

                          const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
                          const signer = createSign('SHA256')
                          signer.update(message); // the message is a string
                          signer.end();
                          signer.sign(privatekey, 'base64'); 

                          Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

                          I attempted to create a public key only pem string as below

                          function convert_raw_ec_key(raw_key) {
                          return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
                          }
                          const pemstr = `-----BEGIN PUBLIC KEY-----
                          ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
                          -----END PUBLIC KEY-----`;
                          const myv = createVerify('SHA256');
                          myv.update(message);// the message is a string
                          myv.end();
                          const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
                          assert(true === result); // but this fails because result is false
                          

                          Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

                          Many thanks.

                          Minimal Reproduction

                          1. Sign
                            1. Create the pem string from the private key and public key
                            2. Pass the pem string to createPrivateKey({key: pem})
                            3. sign the message with createSign(), update(), end(), then sign() for generating signature
                          2. Verify
                            1. Create the pem string from the public key
                            2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

                          Output

                          const result = verify.verify(pem, Buffer.from(signature, 'base64'));
                          console.log(result );
                          assert(true === result);
                          console show the result is false, and assert also fail as the result is false.

                          Before You Submit

                          • I have looked for issues that already exist before submitting this
                          • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

                          Activity

                          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                              Skip to content

                              How to verify the signed message against the signature with raw ec public key only #4447

                              Description

                              @chlin501

                              Node.js Version

                              v20.14.0

                              NPM Version

                              v9.2.0

                              Operating System

                              Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

                              Subsystem

                              crypto

                              Description

                              I have a process which receives a signed message, its corresponded signature, as well as a raw ec public key from a client. The raw ec public key is a 88 chars length base64 string. An example is BEAgXhzprs3lhokv0ESvgXnsMn3FlOLdkyqCJ56UyzJWhQvaVvcQXQR/TuaW85aJKi5uUQnweCr+zTLDLZMB6Ds=. And this raw ec public key is generated by

                              const gen = createECDH('prime256v1');
                              gen.generateKeys();
                              return { publicKey: gen.getPublicKey('base64'),
                              privateKey: gen.getPrivateKey('base64')
                              };
                              

                              And the way to sign is done by

                              const privatekey = createPrivateKey({ key: pem }); // pem is a string created from the method like this link https://gist.github.com/canterberry/bf190ae6402265751e51725be535a4e4
                              const signer = createSign('SHA256')
                              signer.update(message); // the message is a string
                              signer.end();
                              signer.sign(privatekey, 'base64'); 

                              Now the problem is the process that needs to verify the signed message and the corresponded signature is at another machine. So that machine do not have private key, thus I can't recreate pem file from the private and the public key.

                              I attempted to create a public key only pem string as below

                              function convert_raw_ec_key(raw_key) {
                              return Buffer.concat([Buffer.from('MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgA', 'base64'), Buffer.from(raw_key, 'base64')]);
                              }
                              const pemstr = `-----BEGIN PUBLIC KEY-----
                              ${conver_raw_ec_key(client_raw_ec_key).toString('base64')}
                              -----END PUBLIC KEY-----`;
                              const myv = createVerify('SHA256');
                              myv.update(message);// the message is a string
                              myv.end();
                              const result = myv.verify(pemstr, Buffer.from(signature, 'base64'));
                              assert(true === result); // but this fails because result is false
                              

                              Unfortunately, the result value is false. How can I reconstruct the public key so that it can be passed as the parameter to the verify() method for verifying the signed message?

                              Many thanks.

                              Minimal Reproduction

                              1. Sign
                                1. Create the pem string from the private key and public key
                                2. Pass the pem string to createPrivateKey({key: pem})
                                3. sign the message with createSign(), update(), end(), then sign() for generating signature
                              2. Verify
                                1. Create the pem string from the public key
                                2. Verify the message createVerify(), update(), end(), then verify() with the signed message and the signature provided at the sign stage

                              Output

                              const result = verify.verify(pem, Buffer.from(signature, 'base64'));
                              console.log(result );
                              assert(true === result);
                              console show the result is false, and assert also fail as the result is false.

                              Before You Submit

                              • I have looked for issues that already exist before submitting this
                              • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

                              Activity

                              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions