CVE-2016-1000341
Description
In the Bouncy Castle JCE Provider version 1.55 and earlier DSA signature generation is vulnerable to timing attack. Where timings can be closely observed for the generation of signatures, the lack of blinding in 1.55, or earlier, may allow an attacker to gain information about the signature's k value and ultimately the private value as well.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
DSA signature generation in Bouncy Castle JCE Provider 1.55 and earlier lacks blinding, allowing timing attacks that leak the private key.
Vulnerability
The Bouncy Castle JCE Provider versions 1.55 and earlier are vulnerable to a timing attack during DSA signature generation due to the lack of blinding. This allows an attacker who can closely observe signature generation timings to infer information about the ephemeral k value and ultimately recover the private key [3][4].
Exploitation
An attacker with the ability to monitor timing variations during DSA signature generation (e.g., via network latency or local measurement) can perform a timing attack. By correlating observed timings with known data, the attacker can deduce the k value used in the signing process and subsequently derive the private key.
Impact
Successful exploitation results in the disclosure of the DSA private key. This compromises all cryptographic operations relying on that key, including digital signature forgery and identity impersonation.
Mitigation
Users should upgrade to Bouncy Castle version 1.56 or later, which includes blinding in DSA signature generation. Red Hat Fuse 7.1 (RHSA-2018:2669 [3]) and Ubuntu (USN-3727-1 [4]) have released updates addressing this vulnerability. No workaround is available for unpatched versions.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.bouncycastle:bcprov-jdk14Maven | < 1.56 | 1.56 |
org.bouncycastle:bcprov-jdk15Maven | < 1.56 | 1.56 |
org.bouncycastle:bcprov-jdk15onMaven | < 1.56 | 1.56 |
Affected products
4- ghsa-coords4 versionspkg:maven/org.bouncycastle/bcprov-jdk14pkg:maven/org.bouncycastle/bcprov-jdk15pkg:maven/org.bouncycastle/bcprov-jdk15onpkg:rpm/opensuse/bouncycastle&distro=openSUSE%20Tumbleweed
< 1.56+ 3 more
- (no CPE)range: < 1.56
- (no CPE)range: < 1.56
- (no CPE)range: < 1.56
- (no CPE)range: < 1.68-3.2
Patches
1acaac81f96feadded randomizer to DSA signature generation
3 files changed · +37 −8
core/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java+10 −1 modified@@ -95,7 +95,8 @@ public BigInteger[] generateSignature( BigInteger k = kCalculator.nextK(); - BigInteger r = params.getG().modPow(k, params.getP()).mod(q); + // the randomizer is to conceal timing information related to k and x. + BigInteger r = params.getG().modPow(k.add(getRandomizer(q, random)), params.getP()).mod(q); k = k.modInverse(q).multiply(m.add(x.multiply(r))); @@ -163,4 +164,12 @@ protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided) { return !needed ? null : (provided != null) ? provided : new SecureRandom(); } + + private BigInteger getRandomizer(BigInteger q, SecureRandom provided) + { + // Calculate a random multiple of q to add to k. Note that g^q = 1 (mod p), so adding multiple of q to k does not change r. + int randomBits = 7; + + return new BigInteger(randomBits, provided != null ? provided : new SecureRandom()).add(BigInteger.valueOf(128)).multiply(q); + } }
core/src/test/java/org/bouncycastle/crypto/test/DSATest.java+24 −6 modified@@ -44,7 +44,7 @@ public class DSATest byte[] keyData = Hex.decode("b5014e4b60ef2ba8b6211b4062ba3224e0427dd3"); SecureRandom keyRandom = new FixedSecureRandom( - new FixedSecureRandom.Source[] { new FixedSecureRandom.Data(keyData), new FixedSecureRandom.Data(keyData) }); + new FixedSecureRandom.Source[] { new FixedSecureRandom.Data(keyData), new FixedSecureRandom.Data(keyData), new FixedSecureRandom.Data(Hex.decode("01020304"))}); BigInteger pValue = new BigInteger("8df2a494492276aa3d25759bb06869cbeac0d83afb8d0cf7cbb8324f0d7882e5d0762fc5b7210eafc2e9adac32ab7aac49693dfbf83724c2ec0736ee31c80291", 16); BigInteger qValue = new BigInteger("c773218c737ec8ee993b4f2ded30f48edace915f", 16); @@ -165,7 +165,11 @@ private void testDSAsha3(int size, BigInteger s) "A5613957D7E5C7A6D5A5834B4CB069E0831753ECF65BA02B", 16); DSAPrivateKeyParameters priKey = new DSAPrivateKeyParameters(x, dsaParams); - SecureRandom k = new TestRandomBigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"); + SecureRandom k = new FixedSecureRandom( + new FixedSecureRandom.Source[] { + new FixedSecureRandom.BigInteger(BigIntegers.asUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))), + new FixedSecureRandom.Data(Hex.decode("01020304")) + }); byte[] M = Hex.decode("1BD4ED430B0F384B4E8D458EFF1A8A553286D7AC21CB2F6806172EF5F94A06AD"); @@ -287,7 +291,10 @@ private void dsa2Test1() DSASigner signer = new DSASigner(); - signer.init(true, new ParametersWithRandom(kp.getPrivate(), new TestRandomBigInteger("349C55648DCF992F3F33E8026CFAC87C1D2BA075", 16))); + signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom( + new FixedSecureRandom.Source[] { + new FixedSecureRandom.BigInteger("349C55648DCF992F3F33E8026CFAC87C1D2BA075"), + new FixedSecureRandom.Data(Hex.decode("01020304")) }))); byte[] msg = Hex.decode("A9993E364706816ABA3E25717850C26C9CD0D89D"); @@ -404,7 +411,11 @@ private void dsa2Test2() DSASigner signer = new DSASigner(); - signer.init(true, new ParametersWithRandom(kp.getPrivate(), new TestRandomData(Hex.decode("735959CC4463B8B440E407EECA8A473BF6A6D1FE657546F67D401F05")))); + signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom( + new FixedSecureRandom.Source[] { + new FixedSecureRandom.BigInteger(Hex.decode("735959CC4463B8B440E407EECA8A473BF6A6D1FE657546F67D401F05")), + new FixedSecureRandom.Data(Hex.decode("01020304")) + }))); byte[] msg = Hex.decode("23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7"); @@ -520,7 +531,11 @@ private void dsa2Test3() DSASigner signer = new DSASigner(); - signer.init(true, new ParametersWithRandom(kp.getPrivate(), new TestRandomData(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")))); + signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom( + new FixedSecureRandom.Source[] { + new FixedSecureRandom.BigInteger(Hex.decode("0CAF2EF547EC49C4F3A6FE6DF4223A174D01F2C115D49A6F73437C29A2A8458C")), + new FixedSecureRandom.Data(Hex.decode("01020304")) + }))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"); @@ -651,7 +666,10 @@ private void dsa2Test4() DSASigner signer = new DSASigner(); - signer.init(true, new ParametersWithRandom(kp.getPrivate(), new TestRandomData(Hex.decode("A6902C1E6E3943C5628061588A8B007BCCEA91DBF12915483F04B24AB0678BEE")))); + signer.init(true, new ParametersWithRandom(kp.getPrivate(), new FixedSecureRandom( + new FixedSecureRandom.Source[] + { new FixedSecureRandom.BigInteger("A6902C1E6E3943C5628061588A8B007BCCEA91DBF12915483F04B24AB0678BEE"), + new FixedSecureRandom.Data(Hex.decode("01020304")) }))); byte[] msg = Hex.decode("BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD");
prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java+3 −1 modified@@ -686,7 +686,9 @@ private void testDSAsha3(ASN1ObjectIdentifier sigOid, int size, BigInteger s) private void doDsaTest(String sigName, BigInteger s, KeyFactory ecKeyFact, DSAPublicKeySpec pubKey, DSAPrivateKeySpec priKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, InvalidKeySpecException, SignatureException { - SecureRandom k = new TestRandomBigInteger(BigIntegers.asUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))); + SecureRandom k = new FixedSecureRandom( + new FixedSecureRandom.Source[] { new FixedSecureRandom.BigInteger(BigIntegers.asUnsignedByteArray(new BigInteger("72546832179840998877302529996971396893172522460793442785601695562409154906335"))), + new FixedSecureRandom.Data(Hex.decode("01020304")) }); byte[] M = Hex.decode("1BD4ED430B0F384B4E8D458EFF1A8A553286D7AC21CB2F6806172EF5F94A06AD");
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- access.redhat.com/errata/RHSA-2018:2669ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2927ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-r9ch-m4fh-fc7qghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-1000341ghsaADVISORY
- usn.ubuntu.com/3727-1/mitrevendor-advisoryx_refsource_UBUNTU
- github.com/bcgit/bc-java/commit/acaac81f96fec91ab45bd0412beaf9c3acd8defaghsax_refsource_CONFIRMWEB
- lists.debian.org/debian-lts-announce/2018/07/msg00009.htmlghsamailing-listx_refsource_MLISTWEB
- security.netapp.com/advisory/ntap-20181127-0004ghsaWEB
- security.netapp.com/advisory/ntap-20181127-0004/mitrex_refsource_CONFIRM
- usn.ubuntu.com/3727-1ghsaWEB
- www.oracle.com/security-alerts/cpuoct2020.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.