High severity8.7NVD Advisory· Published Mar 23, 2026· Updated Apr 29, 2026
CVE-2026-4601
CVE-2026-4601
Description
Versions of the package jsrsasign before 11.1.1 are vulnerable to Missing Cryptographic Step via the KJUR.crypto.DSA.signWithMessageHash process in the DSA signing implementation. An attacker can recover the private key by forcing r or s to be zero, so the library emits an invalid signature without retrying, and then solves for x from the resulting signature.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
jsrsasignnpm | < 11.1.1 | 11.1.1 |
Affected products
1- cpe:2.3:a:jsrsasign_project:jsrsasign:*:*:*:*:*:node.js:*:*Range: <11.1.1
Patches
10710e392ec35Merge pull request #645 from Kr0emer/fix/bug-001-sign_s_zero
2 files changed · +47 −9
src/dsa-2.0.js+12 −9 modified@@ -164,21 +164,24 @@ KJUR.crypto.DSA = function() { var y = this.y; // public key (p q g y) var x = this.x; // private key - // NIST FIPS 186-4 4.5 DSA Per-Message Secret Number (p18) - // 1. get random k where 0 < k < q - var k = KJUR.crypto.Util.getRandomBigIntegerMinToMax(BigInteger.ONE.add(BigInteger.ONE), - q.subtract(BigInteger.ONE)); - // NIST FIPS 186-4 4.6 DSA Signature Generation (p19) // 2. get z where the left most min(N, outlen) bits of Hash(M) var hZ = sHashHex.substr(0, q.bitLength() / 4); var z = new BigInteger(hZ, 16); - // 3. get r where (g^k mod p) mod q, r != 0 - var r = (g.modPow(k,p)).mod(q); + var k, r, s; + do { + // NIST FIPS 186-4 4.5 DSA Per-Message Secret Number (p18) + // 1. get random k where 0 < k < q + k = KJUR.crypto.Util.getRandomBigIntegerMinToMax(BigInteger.ONE.add(BigInteger.ONE), + q.subtract(BigInteger.ONE)); + + // 3. get r where (g^k mod p) mod q, r != 0 + r = (g.modPow(k,p)).mod(q); - // 4. get s where k^-1 (z + xr) mod q, s != 0 - var s = (k.modInverse(q).multiply(z.add(x.multiply(r)))).mod(q); + // 4. get s where k^-1 (z + xr) mod q, s != 0 + s = (k.modInverse(q).multiply(z.add(x.multiply(r)))).mod(q); + } while (r.compareTo(BigInteger.ZERO) == 0 || s.compareTo(BigInteger.ZERO) == 0); // 5. signature (r, s) var result = KJUR.asn1.ASN1Util.jsonToASN1HEX({
test/qunit-do-dsa.html+35 −0 modified@@ -129,6 +129,41 @@ ok(dsa2.verifyWithMessageHash(sHashHex, hSigVal), ""); }); +test("signWithMessageHash retries when s is zero", function() { + var pSmall = new BigInteger("17", 16); + var qSmall = new BigInteger("0b", 16); + var gSmall = new BigInteger("04", 16); + var xSmall = new BigInteger("03", 16); + var ySmall = gSmall.modPow(xSmall, pSmall); + var dsaPrv = new KJUR.crypto.DSA(); + dsaPrv.setPrivate(pSmall, qSmall, gSmall, null, xSmall); + var dsaPub = new KJUR.crypto.DSA(); + dsaPub.setPublic(pSmall, qSmall, gSmall, ySmall); + + var kList = [new BigInteger("2", 10), new BigInteger("3", 10)]; + var kIdx = 0; + var fOrig = KJUR.crypto.Util.getRandomBigIntegerMinToMax; + + var r0 = gSmall.modPow(kList[0], pSmall).mod(qSmall); + var z = qSmall.subtract(xSmall.multiply(r0).mod(qSmall)).mod(qSmall); + var sHashHex = z.toString(16); + + KJUR.crypto.Util.getRandomBigIntegerMinToMax = function() { + return kList[kIdx++]; + }; + + try { + var hSigVal = dsaPrv.signWithMessageHash(sHashHex); + var rs = dsaPrv.parseASN1Signature(hSigVal); + ok(kIdx >= 2, "retry with a new k"); + ok(rs[0].compareTo(BigInteger.ZERO) != 0, "r != 0"); + ok(rs[1].compareTo(BigInteger.ZERO) != 0, "s != 0"); + ok(dsaPub.verifyWithMessageHash(sHashHex, hSigVal), "signature verifies"); + } finally { + KJUR.crypto.Util.getRandomBigIntegerMinToMax = fOrig; + } +}); + test("readPKCS5PrvKeyHex d1", function() { var key = new KJUR.crypto.DSA(); key.readPKCS5PrvKeyHex(D1PRVP5HEX);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/kjur/jsrsasign/commit/0710e392ec35de697ce11e4219c988ba2b5fe0ebnvdPatchWEB
- gist.github.com/Kr0emer/93789fe6efe5519db9692d4ad1dad586nvdExploitMitigationThird Party AdvisoryWEB
- github.com/advisories/GHSA-w8q8-93cx-6h7rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-4601ghsaADVISORY
- security.snyk.io/vuln/SNYK-JS-JSRSASIGN-15370941nvdThird Party AdvisoryWEB
- github.com/kjur/jsrsasign/pull/645nvdIssue TrackingWEB
News mentions
0No linked articles in our index yet.