You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The signature and verification of SM2 return incorrect results in crypto.createSign and crypto.createVerify #53761
Darwin air.lan 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:19:05 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T8112 arm64
Subsystem
crypto
What steps will reproduce the bug?
When using crypto.createSign to sign SM2, I got an incorrect signature. The same issue occurs with crypto.createVerify.
constcrypto=require('crypto');constdata="AABB";varkeys={privateKey: crypto.createPrivateKey(`-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbjCNHopgvyGVfLaPPamI9E9lf6jXT+xm1Pns1t/xQTihRANCAATV+I7HUGF2gC+miVl3JfjpoZaU2hrZQqHwKUNtIDE/uxxWNLBbYKaiLOWrbYA8skrWQWl3RkbXW4ZI28afRw9g-----END PRIVATE KEY-----`),publicKey: crypto.createPublicKey(`-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1fiOx1BhdoAvpolZdyX46aGWlNoa2UKh8ClDbSAxP7scVjSwW2Cmoizlq22APLJK1kFpd0ZG11uGSNvGn0cPYA==-----END PUBLIC KEY-----`)};varsig=crypto.createSign('sm3').update(data).sign(keys.privateKey);// var sig = crypto.sign('sm3', data, keys.privateKey);varok=crypto.verify('sm3',data,keys.publicKey,sig);console.log("verify: ",ok);
How often does it reproduce? Is there a required condition?
always.
What is the expected behavior? Why is that the expected behavior?
I've made a few changes to the code for better logging, and here is my output:
constcrypto=require('crypto');constdata="AABB";// Define the private and public keysconstprivateKeyPEM=`-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbjCNHopgvyGVfLaPPamI9E9lf6jXT+xm1Pns1t/xQTihRANCAATV+I7HUGF2gC+miVl3JfjpoZaU2hrZQqHwKUNtIDE/uxxWNLBbYKaiLOWrbYA8skrWQWl3RkbXW4ZI28afRw9g-----END PRIVATE KEY-----`;constpublicKeyPEM=`-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1fiOx1BhdoAvpolZdyX46aGWlNoa2UKh8ClDbSAxP7scVjSwW2Cmoizlq22APLJK1kFpd0ZG11uGSNvGn0cPYA==-----END PUBLIC KEY-----`;// Create the private and public key objectsconstprivateKey=crypto.createPrivateKey(privateKeyPEM);constpublicKey=crypto.createPublicKey(publicKeyPEM);// Log the private and public keysconsole.log("Private Key:");console.log(privateKey.export({type: 'pkcs8',format: 'pem'}));console.log("Public Key:");console.log(publicKey.export({type: 'spki',format: 'pem'}));// Create the signature using the private keyconstsign=crypto.createSign('sm3');sign.update(data);constsignature=sign.sign(privateKey);// Log the signatureconsole.log("Signature:");console.log(signature.toString('hex'));// Verify the signature using the public key via crypto.createVerifyconstverify=crypto.createVerify('sm3');verify.update(data);constisVerified=verify.verify(publicKey,signature);// Log the verification resultconsole.log("Signature verified (via crypto.createVerify):",isVerified);// Verify the signature using the public key via crypto.verifyconstverify2=crypto.verify('sm3',data,publicKey,signature);console.log("Signature verified (via crypto.verify):",verify2);
constcrypto=require('crypto');constdata="AABB";varkeys={privateKey: crypto.createPrivateKey(`-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbjCNHopgvyGVfLaPPamI9E9lf6jXT+xm1Pns1t/xQTihRANCAATV+I7HUGF2gC+miVl3JfjpoZaU2hrZQqHwKUNtIDE/uxxWNLBbYKaiLOWrbYA8skrWQWl3RkbXW4ZI28afRw9g-----END PRIVATE KEY-----`),publicKey: crypto.createPublicKey(`-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1fiOx1BhdoAvpolZdyX46aGWlNoa2UKh8ClDbSAxP7scVjSwW2Cmoizlq22APLJK1kFpd0ZG11uGSNvGn0cPYA==-----END PUBLIC KEY-----`)};// var sig = crypto.createSign('sm3').update(data).sign(keys.privateKey);varsig=crypto.sign('sm3',data,keys.privateKey);varok=crypto.createVerify('sm3').update(data).verify(keys.publicKey,sig);console.log("verify: ",ok);
constcrypto=require('crypto');// Data to be signed and verifiedconstdata="AABB";// Define the private and public keysconstprivateKeyPEM=`-----BEGIN PRIVATE KEY-----MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbjCNHopgvyGVfLaPPamI9E9lf6jXT+xm1Pns1t/xQTihRANCAATV+I7HUGF2gC+miVl3JfjpoZaU2hrZQqHwKUNtIDE/uxxWNLBbYKaiLOWrbYA8skrWQWl3RkbXW4ZI28afRw9g-----END PRIVATE KEY-----`;constpublicKeyPEM=`-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1fiOx1BhdoAvpolZdyX46aGWlNoa2UKh8ClDbSAxP7scVjSwW2Cmoizlq22APLJK1kFpd0ZG11uGSNvGn0cPYA==-----END PUBLIC KEY-----`;// Function to create private key objectfunctioncreatePrivateKey(privateKeyPEM){returncrypto.createPrivateKey(privateKeyPEM);}// Function to create public key objectfunctioncreatePublicKey(publicKeyPEM){returncrypto.createPublicKey(publicKeyPEM);}// Array of signer functionsconstSIGNERS=[// Via crypto.createSign(data,privateKey)=>{constsign=crypto.createSign('sm3');sign.update(data);returnsign.sign(privateKey);},// Via crypto.sign(data,privateKey)=>{returncrypto.sign('sm3',Buffer.from(data),{key: privateKey});}];// Array of verifier functionsconstVERIFIERS=[// Via crypto.createVerify(data,signature,publicKey)=>{constverify=crypto.createVerify('sm3');verify.update(data);returnverify.verify(publicKey,signature);},// Via crypto.verify(data,signature,publicKey)=>{returncrypto.verify('sm3',Buffer.from(data),publicKey,signature);}];// Function to sign data using all signers and verify using all verifiersfunctionsignAndVerifyAll(data,privateKey,publicKey){constresults=SIGNERS.flatMap(signer=>{constsignature=signer(data,privateKey);returnVERIFIERS.map(verifier=>{return{"Sign Method": SIGNERS.indexOf(signer)===0 ? 'crypto.createSign' : 'crypto.sign',"Verify Method": VERIFIERS.indexOf(verifier)===0 ? 'crypto.createVerify' : 'crypto.verify',"Signature": signature.toString('hex'),"Result": verifier(data,signature,publicKey)};});});returnresults;}// Create private and public key objectsconstprivateKey=createPrivateKey(privateKeyPEM);constpublicKey=createPublicKey(publicKeyPEM);// Sign and verify data using all methodsconstresults=signAndVerifyAll(data,privateKey,publicKey);// Output results in a tableconsole.table(results);
This issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 240 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.
Activity
avivkeller commentedon Jul 8, 2024
(+
repro-exists)I've made a few changes to the code for better logging, and here is my output:
This seems to only affect
crypto.verify, CC @nodejs/cryptoavivkeller commentedon Jul 8, 2024
That being said, I believe the issue title is misleading.
crypto.createVerifyappears to be fine, it'scrypto.verifythat is affected, right?tniessen commentedon Jul 8, 2024
Related: #37066
xicilion commentedon Jul 8, 2024
My test results are as follows:
So the results of crypto.createSign and crypto.createVerify on SM2 are both incorrect.
avivkeller commentedon Jul 8, 2024
Can you provide example code with
createVerify? I'm unable to reproduce that part.xicilion commentedon Jul 8, 2024
avivkeller commentedon Jul 8, 2024
Thanks! I understand now. My reproduction used
createSign, which worked, this is weird indeed. @tniessenconfirmed-bug?avivkeller commentedon Jul 8, 2024
I've generated the table above to demonstrate which methods are incompatible.
avivkeller commentedon Jul 8, 2024
So
crypto.createXXXseems to have the wrong algorithm, IIUCxicilion commentedon Jul 8, 2024
crypto.sign and crypto.verify are correct.
avivkeller commentedon Jul 8, 2024
Thanks for the excellent info! When the @nodejs/crypto team gets a chance to look at this issue, they will be able to help even more!
github-actions commentedon May 2, 2026
This issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
github-actions commentedon Jun 1, 2026
This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 240 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.