sm-crypto: Predictable SM2 key generation in Node.js: default RNG uses Math.random + wall clock
Affects sm-cryptoSource GCVE Database
CVSS 9.1 Critical · fixed in 0.5.0 : patch sm-crypto as a priority.
Data as of 07/25/2026, 23:51:39 UTC
- Patch
- Available – fixed in 0.5.0
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:NWhat to do
Affected software
| Product | Affected | Fixed in |
|---|---|---|
| npmsm-crypto | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
AI-suggested
Users should avoid using the default key generation in Node.js environments until a patched version is released. Monitor the vendor or repository for updates addressing this issue. Since the vulnerability arises from the fallback to non-cryptographic RNG sources, a potential mitigation is to patch or override the RNG initialization to use Node.js's globalThis.crypto.getRandomValues or another cryptographically secure RNG before loading sm-crypto, but this requires custom intervention.
Description
The npm package sm-crypto version 0.4.0 and earlier generates SM2 private keys and signing ephemeral scalars using a predictable random number generator in Node.js environments. The library relies on jsbn's SecureRandom, which attempts to seed from window.crypto.getRandomValues in browsers but falls back to non-cryptographic sources (Math.random and wall clock time) in Node.js because window is undefined. This fallback results in keys and ephemeral values that are predictable by attackers who can observe some outputs of Math.random and estimate the generation time. This vulnerability affects the default key generation path without requiring special configuration.
Impact
An attacker who can observe some outputs of Math.random and estimate the approximate time of key generation can predict SM2 private keys and signing ephemeral scalars generated by sm-crypto in Node.js. This compromises the confidentiality and integrity of cryptographic operations relying on these keys, enabling key recovery and signature forgery. The vulnerability affects all users of the default key generation path in sm-crypto versions prior to 0.5.0 running in Node.js environments.
Summary
sm-crypto@0.4.0 uses jsbn's SecureRandom for SM2 key generation. In browsers, SecureRandom seeds an ARC4 stream from window.crypto.getRandomValues, providing cryptographically secure randomness. However, in Node.js, window is undefined, so the secure seeding branch is skipped. Instead, the RNG pool is seeded from Math.random (a recoverable xorshift128+ PRNG) and Date.getTime(), both of which are non-cryptographic and attacker-estimable. Consequently, SM2 private keys and signing ephemeral scalars generated by the default no-argument call path are predictable. A proof-of-concept demonstrates that pinning Math.random and the clock before loading sm-crypto results in deterministic key generation, confirming the vulnerability. This issue affects sm-crypto versions before 0.5.0 and is not mitigated by any existing fixes or configuration options.
Weaknesses
- CWE-338Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG) (opens in a new tab)
Base weaknessLikelihood of exploit: MediumOWASP Top 10 A04:2025: Cryptographic Failures (opens in a new tab)
The product uses a Pseudo-Random Number Generator (PRNG) in a security context, but the PRNG's algorithm is not cryptographically strong.