
Factoring "short-sleeve" RSA keys with polynomials
Trail of Bits, working with Hanno Böck's badkeys project, found hundreds of real-world RSA/DSA keys ("short-sleeve" keys) with regularly spaced blocks of zero bits caused by a big-integer/RNG type mismatch in CompleteFTP's key-generation code (versions 10.0.0-12.0.0 for RSA, through 23.0.4 for DSA). They developed a polynomial-factorization technique — converting the modulus to a polynomial with small coefficients via base-2^w representation and factoring the polynomial instead of the integer — to recover 603 RSA private keys and 74 DSA private keys from internet scans, and reverse-engineered the CompleteFTP binary with ILSpy to find the exact Array.Copy bug responsible. EnterpriseDT shipped patched key generation and a key-checking tool, and badkeys now detects this weakness.
What it is
Trail of Bits, working with Hanno Böck's badkeys project, identified "short-sleeve" RSA and DSA keys — moduli whose big-integer limbs contain structured blocks of zero bits, leaving only a small contiguous slice of each limb filled with random data. Such keys can be factored quickly using a polynomial technique. Two patterns emerged; pattern 2 was traced to a big-integer type-mismatch bug in EnterpriseDT's CompleteFTP file transfer software. Pattern 1 remains unexplained.
How it works
A big integer is stored as an array of machine-sized limbs. Reading the modulus $n$ in its base-$2^w$ representation (where $w$ is the limb width) turns each limb into a polynomial coefficient: $a = \sum_i a_i 2^{wi}$ becomes $f_n(x) = \sum_i a_i x^i$, with $f_n(2^w)=n$. Because evaluation commutes with multiplication and addition, if $p$ and $q$ also have small-coefficient polynomials then $f_n(x)=f_p(x)\cdot f_q(x)$. Factoring a polynomial is easy, so you factor $f_n(x)$, then evaluate the factors at $2^w$ to recover $p$ and $q$. This works only because the zero blocks force exceptionally small coefficients — correctly generated primes yield full $w$-bit coefficients, so the attack fails on normal keys. Pattern 1 reads as 128-bit limbs, pattern 2 as 32-bit limbs. The post notes it omits one key insight needed for the real-world moduli (full derivation at the end of the article).
Preconditions / Affected
The two patterns differ in origin and scope:
- Pattern 1 (128-bit limbs): seen in Certificate Transparency logs for certificates issued to large organizations including Yahoo and Verizon, and on some NetApp-running devices. Those certs have expired; the generating product is unidentified.
- Pattern 2 (32-bit limbs, CompleteFTP): note the version ranges differ by key type — RSA keys from v10.0.0–12.0.0 (Dec 2016–Mar 2019); DSA keys from v10.0.0–23.0.4 (Dec 2016–Dec 2023). (The existing summary's single 10.0.0–23.0.4 range applies to DSA; the RSA window is narrower.) Recovered: 603 unique RSA private keys, 74 DSA keys, from SSH host scans.
What to do
If you generated CompleteFTP host keys between December 2016 and December 2023, use CompleteFTP's released tool to check whether your keys need regenerating, and regenerate affected keys. More broadly, the authors suggest tailoring cryptanalytic checks for this failure mode, since independent implementations produced similar bugs — badkeys detection covers these patterns.
Caveats
Only a small minority of internet hosts are affected. Pattern 1's source was never confirmed — the contacted organizations did not respond. The blog deliberately omits one insight required to factor the real moduli, so the "basic version" described is not directly sufficient.
Organisations named here
- EnterpriseDT
- Hanno Böck
- Nadia Heninger
Technologies named here
- badkeys
- CompleteFTP
- ILSpy
- CompleteFTP RSA key generation on Linux
- CompleteFTP standalone key-check tool
- General Number Field Sieve
- .NET
- SSH
Techniques named here
- Polynomial-based factorization of 'short-sleeve' RSA moduli
- Bit-shift trick for small-coefficient polynomials
- Statistical/structural detection of biased RSA moduli
- Reverse engineering of key-generation code
- DSA private key recovery from biased 160-bit exponent
- Historical SSH scan trend analysis
Related in AppSec
Flowise MCP Security Bypass Enables RCE
Inside an Oracle Database SQL Injection Attack | Huntress
OASIS
