Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
2 tasks done
chlin501 opened this issue Jul 12, 2024 · 1 comment
Open
2 tasks done
Labels

Comments

@chlin501
Copy link

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
@RedYetiDev
Copy link
Member

CC @nodejs/crypto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants