Moderate severityNVD Advisory· Published Jun 17, 2012· Updated Apr 29, 2026
CVE-2012-2417
CVE-2012-2417
Description
PyCrypto before 2.6 does not produce appropriate prime numbers when using an ElGamal scheme to generate a key, which reduces the signature space or public key space and makes it easier for attackers to conduct brute force attacks to obtain the private key.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
PyCryptoPyPI | < 2.6 | 2.6 |
Affected products
21cpe:2.3:a:dlitz:pycrypto:*:*:*:*:*:*:*:*+ 20 more
- cpe:2.3:a:dlitz:pycrypto:*:*:*:*:*:*:*:*range: <=2.5
- cpe:2.3:a:dlitz:pycrypto:1.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.1:alpha2:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha1:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha2:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha3:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha4:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha5:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:1.9:alpha6:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.0:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.1.0:alpha1:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.1.0:alpha2:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.1.0:beta1:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.2:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.3:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.4:*:*:*:*:*:*:*
- cpe:2.3:a:dlitz:pycrypto:2.4.1:*:*:*:*:*:*:*
Patches
19f912f13df99Fix to bug #985164 (ElGamal key generation). Fix to missing range check in signature verification.
1 file changed · +40 −24
lib/Crypto/PublicKey/ElGamal.py+40 −24 modified@@ -110,6 +110,9 @@ class error (Exception): def generate(bits, randfunc, progress_func=None): """Randomly generate a fresh, new ElGamal key. + The key will be safe for use for both encryption and signature + (although it should be used for **only one** purpose). + :Parameters: bits : int Key length, or size (in bits) of the modulus *p*. @@ -131,37 +134,48 @@ def generate(bits, randfunc, progress_func=None): :Return: An ElGamal key object (`ElGamalobj`). """ obj=ElGamalobj() - # Generate prime p + # Generate a safe prime p + # See Algorithm 4.86 in Handbook of Applied Cryptography if progress_func: progress_func('p\n') - obj.p=bignum(getPrime(bits, randfunc)) - # Generate random number g + while 1: + q = bignum(getPrime(bits-1, randfunc)) + obj.p = 2*q+1 + if number.isPrime(obj.p, randfunc=randfunc): + break + # Generate generator g + # See Algorithm 4.80 in Handbook of Applied Cryptography + # Note that the order of the group is n=p-1=2q, where q is prime if progress_func: progress_func('g\n') - size=bits-1-(ord(randfunc(1)) & 63) # g will be from 1--64 bits smaller than p - if size<1: - size=bits-1 - while (1): - obj.g=bignum(getPrime(size, randfunc)) - if obj.g < obj.p: + while 1: + # We must avoid g=2 because of Bleichenbacher's attack described + # in "Generating ElGamal signatures without knowning the secret key", + # 1996 + # + obj.g = number.getRandomRange(3, obj.p, randfunc) + safe = 1 + if pow(obj.g, 2, obj.p)==1: + safe=0 + if safe and pow(obj.g, q, obj.p)==1: + safe=0 + # Discard g if it divides p-1 because of the attack described + # in Note 11.67 (iii) in HAC + if safe and divmod(obj.p-1, obj.g)[1]==0: + safe=0 + # g^{-1} must not divide p-1 because of Khadir's attack + # described in "Conditions of the generator for forging ElGamal + # signature", 2011 + ginv = number.inverse(obj.g, obj.p) + if safe and divmod(obj.p-1, ginv)[1]==0: + safe=0 + if safe: break - size=(size+1) % bits - if size==0: - size=4 - # Generate random number x + # Generate private key x if progress_func: progress_func('x\n') - while (1): - size=bits-1-ord(randfunc(1)) # x will be from 1 to 256 bits smaller than p - if size>2: - break - while (1): - obj.x=bignum(getPrime(size, randfunc)) - if obj.x < obj.p: - break - size = (size+1) % bits - if size==0: - size=4 + obj.x=number.getRandomRange(2, obj.p-1, randfunc) + # Generate public key y if progress_func: progress_func('y\n') obj.y = pow(obj.g, obj.x, obj.p) @@ -326,6 +340,8 @@ def _sign(self, M, K): return (a, b) def _verify(self, M, sig): + if sig[0]<1 or sig[0]>p-1: + return 0 v1=pow(self.y, sig[0], self.p) v1=(v1*pow(sig[0], sig[1], self.p)) % self.p v2=pow(self.g, M, self.p)
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
19- github.com/Legrandin/pycrypto/commit/9f912f13df99ad3421eff360d6a62d7dbec755c2nvdExploitPatchWEB
- secunia.com/advisories/49263nvdVendor Advisory
- github.com/advisories/GHSA-v367-p58w-98h5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-2417ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2012-June/081713.htmlnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2012-June/081759.htmlnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2012-June/081789.htmlnvdWEB
- www.debian.org/security/2012/dsa-2502nvdWEB
- www.mandriva.com/security/advisoriesnvdWEB
- www.openwall.com/lists/oss-security/2012/05/25/1nvdWEB
- bugs.launchpad.net/pycrypto/+bug/985164nvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/75871nvdWEB
- github.com/dlitz/pycrypto/blob/373ea760f21701b162e8c4912a66928ee30d401a/ChangeLognvdWEB
- github.com/pypa/advisory-database/tree/main/vulns/pycrypto/PYSEC-2012-16.yamlghsaWEB
- hermes.opensuse.org/messages/15083589nvdWEB
- web.archive.org/web/20140724111917/http://secunia.com/advisories/49263ghsaWEB
- web.archive.org/web/20200228184120/http://www.securityfocus.com/bid/53687ghsaWEB
- www.osvdb.org/82279nvd
- www.securityfocus.com/bid/53687nvd
News mentions
0No linked articles in our index yet.