Skip to content

Crypto cant sign/verify prehashed inputs #60263

@codermapuche

Description

@codermapuche

Version

Node.js v22.20.0 - Node.js v24.10.0

Platform

all

Subsystem

crypto

What steps will reproduce the bug?

const crypto = require('crypto');

const message		 	= Buffer.from('LmM8PqCO1QIpTse0s+MQEJ7YXOSZuqyjPCJ4tIZ+OrU=', 'base64'),
			prehash 	 	= crypto.createHash('sha256').update(message).digest();

const namedCurve 	= 'secp256k1',
			keyPair 	 	= crypto.generateKeyPairSync('ec', { namedCurve }),
			signature		= crypto.sign(null, prehash, {
											key					: keyPair.privateKey,
											dsaEncoding	: 'ieee-p1363'
										});

console.log(crypto.verify(null, message, {
	key					: keyPair.publicKey,
	dsaEncoding	: 'ieee-p1363'
}, signature), ' message internal-internal (must be false)');

console.log(crypto.verify(null, prehash, {
	key					: keyPair.publicKey,
	dsaEncoding	: 'ieee-p1363'
}, signature), ' prehash internal-internal (must be true)');

// Simple unitary test:
const PUBLIC_KEY_PEM = '-----BEGIN PUBLIC KEY-----\n' +
										 	'MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE6Yvel06IICYJZ/XsuPEFTpDt0aU8dwLK\n' +
										 	'jvgxyYTeZ/vlS49/PDRIr5JDz+QNWFB9ZM9tf4i9SdT0LVtlgRj3dQ==\n' +
										 	'-----END PUBLIC KEY-----',
			publicKey 		 = crypto.createPublicKey(PUBLIC_KEY_PEM),
			signOfPreHash  = Buffer.from('Djv4wD3eWu8lHI3DrN2Dypdrirj+J1rfJD5O1B/Tw8sYy38jms77neECQ0S9LHpnWun+Jb9iOZNbYjH+CoVUnA==', 'base64');

console.log('== BUG HERE ==');

console.log(crypto.verify(null, message, {
	key					: publicKey,
	dsaEncoding	: 'ieee-p1363'
}, signOfPreHash), ' message external-internal (must be false)');

console.log(crypto.verify(null, prehash, {
	key					: publicKey,
	dsaEncoding	: 'ieee-p1363'
}, signOfPreHash), ' prehash external-internal (must be true)');

How often does it reproduce? Is there a required condition?

No precondition required.

What is the expected behavior? Why is that the expected behavior?

When send null to algorithm param i expect that message payload be raw, prehashed, dont want an additional internal rehash. This make impossible verify or sign keeping compatibility with external systems.

What do you see instead?

crypto module ignore my null and place a sha256 algorithm instead, performing a double hash internally.

Additional information

Many external systems provide hash + signarure to verify, but we cannot do this because the implicit rehash of crypto module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.feature requestIssues that request new features to be added to Node.js.

    Type

    No type

    Projects

    Status

    Awaiting Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions