1. Home
  2. /
  3. Download
  4. /
  5. Download Bouncy Castle Java

Download Bouncy Castle for Java

Welcome to the download page for the general edition of Bouncy Castle Java. In addition to the available access options, including GitHub, Maven Central, and direct download, you will find searchable release notes and links to API and other documentation.

 

Bouncy Castle Java
hero-sub-2

GitHub

Access the Bouncy Castle APIs Java package on GitHub, where you can also report issues, join discussions, and contribute to the software.

Documentation 

Explore the Bouncy Castle for Java documentation online for concise guidance and examples.

Join the discussion

You can ask questions and learn from specialists in the Bouncy Castle Java forum on GitHub Discussions. We highly appreciate and value your input.

Report an issue

If you encounter any issues that require attention, feel free to report them in our GitHub repository. 

Release notes

Find out detailed information about the latest release and search in older release notes.

Beta releases

The current working betas, when available, for the next release for JDK 1.8 and later can be found here. If you need a beta to be made available for another version of Java please ask by emailing: feedback-crypto@bouncycastle.org.

Donate to support the Bouncy Castle APIs

Supporting Bouncy Castle is now a substantial effort, the Java API is now over 300,000 lines, the C# one well past 140,000.

Bouncy Castle Java Downloads

The latest Bouncy Castle Java release is 1.85.

Except where otherwise stated, this software is distributed under the regular Bouncy Castle license. For full details of other licenses involved, see Third party licenses

Distribution Files (JAR and ZIP format)

Compiled classes, sources and JavaDoc for Java 1.1.

Checksums

To confirm the integrity of the distributions, checksums are available:

Download Checksums

Maven Central Signing Key

If you are trying to confirm the signatures for artifacts from Maven Central, you can use the public key linked below.

Download bc_maven_public_key.asc

Release notes

Find out detailed information about the latest Bouncy Castle Java releases and search in older release notes.  

Release 1.85.2
7 August, 2026
Defects Fixed The AES-256/CBC Cipher registered against the id_aes256_CBC OID (org.bouncycastle.jcajce.provider.symmetric.AES$CBC256) passed 192 rather tha...

Defects Fixed

  • The AES-256/CBC Cipher registered against the id_aes256_CBC OID (org.bouncycastle.jcajce.provider.symmetric.AES$CBC256) passed 192 rather than 256 as its key size, so a Cipher obtained via that OID and initialised with a password-based key (PKCS12Key, PBKDF1Key, PBKDF2Key or a plain PBEKey), rather than the dedicated PBEWITHSHAAND256BITAES-CBC-BC alias, silently derived only a 192 bit key – an unannounced downgrade to AES-192. Ordinary use with a raw SecretKeySpec was unaffected (github #2390).
  • Constructing BouncyCastleProvider built the AlgorithmParameters.EC SupportedCurves attribute by calling ECNamedCurveTable.getParameterSpec for every registered curve and discarding the result, forcing every lazy curve holder in the table and making provider construction markedly slower than in earlier releases. The attribute is now built with a presence check that does not materialise the parameters (github #2382).
  • KCCMBlockCipher (DSTU7624-128/256/512 CCM mode) returned the input length rather than 0 from getUpdateOutputSize(int), but like CCMBlockCipher/KGCMBlockCipher it buffers all input until doFinal and produces no output on an update. Through the JCA layer this made Cipher.update(input, inOff, inLen, output, outOff) reject a correctly sized output buffer with ShortBufferException when decrypting (github #2354).
  • The PKIX CertPathBuilder matched candidate issuers by subject name only during its depth-first search, so a CertStore containing many self-issued certificates sharing one subject name and never chaining to a trust anchor could be explored as a large number of partial paths. The builder now bounds the nodes visited per build, configurable via org.bouncycastle.x509.max_cert_path_build_nodes (default 262144).
  • BigIntegers value-exact range checks are open-coded again: BigInteger.intValueExact and friends are missing on Android below API level 33 (github #2369).
  • SICBlockCipher.getPosition() propagated its borrow incorrectly for counter increments carrying across 0xFF IV bytes, and skip() moved to the wrong position for backward moves smaller than the current intra-block offset. The full-block-IV counter advance is now bounded at 2^64 blocks, the short-IV range check covers the previously unchecked processBlock path, and the skip/seekTo increment cascades are a constant-time counter addition – fixing the skip(Long.MIN_VALUE) unbounded spin and a near-Long.MAX_VALUE mid-block overflow.
  • An unreachable or failing OCSP responder was reported as a plain CertPathValidatorException with the message “configuration error”, which the revocation checker treats as a definite result, so a connection failure aborted path validation instead of allowing fallback to CRL checking. It is now a recoverable failure naming the responder (github #2372).
  • Salsa20Engine.skip(Long.MIN_VALUE) silently moved nothing while returning as though it had, because negating the argument overflowed back to itself; the move is now split so it either lands exactly or raises the existing past-zero exception. The same applies to the ChaCha family sharing the engine.
  • ReasonsMask.hasNewReasons was written as (_reasons | mask ^ _reasons) != 0, where ^ binds tighter than |, so it reported new reasons for almost any pair of masks rather than testing whether the candidate carried reasons the accumulated mask did not.
  • The RFC 5280 sec. 6.3.3 CRL scope rules – the (b)(1) cRLIssuer check, the (b)(2) issuing distribution point checks, the (c) delta CRL consistency checks and the (d) reasons intersection – are now single-sourced in the new pure-ASN.1 org.bouncycastle.asn1.x509.PKIXCRLValidator, with the provider’s RFC3280CertPathUtilities delegating to it; behaviour and exception messages are unchanged. The pkix module’s copy of the checks is unchanged on this release.
  • HQC (org.bouncycastle.pqc.crypto.hqc) leaked secret-derived data through two timing/cache side channels: its GF(2^8) arithmetic used log/exp lookup tables, so the accessed cache line depended on secret operands, and its fixed-weight support sampler used data-dependent control flow. The GF arithmetic is now table-free and the sampler branch-free and fixed-count, with an exhaustive GF regression test. Reported by the Robusta team.
  • NTRU’s mod3 and modQ reductions are now division-free, restoring the reference implementation’s fold-and-select and its MODQ mask so the secret operand is not exposed through division latency. Reported by the Robusta team.
  • The PBKDF2 keyLength taken from a BCFKS keystore is now bounded before deriving, matching the iteration count caps beside it and stopping the keyLength * 8 conversion overflowing into a NegativeArraySizeException.
  • BMPString content was read by sizing a char[] from the declared length before any content had arrived, so a short crafted header could drive an allocation of up to 1GB and an OutOfMemoryError out of a parse API declaring IOException. It is now read through DefiniteLengthInputStream.toByteArray, which grows its buffer as bytes arrive.
  • The HPKE context advanced its sequence number even when Seal/Open failed, so a rejected ciphertext desynchronised the receiving context from the sender; it now advances only on success per RFC 9180 sec. 5.2, and the section’s message limit is enforced rather than wrapping the counter.
  • Sorting the elements of a DER SET re-derived an element’s encoding every time the insertion sort shifted it, costing O(N^2) encodings. Each element is now encoded once and the ordering uses a stable O(N log N) sort; the j2me tree keeps its insertion sort, memoised, since CLDC has no java.util.Arrays.
  • X500Name.hashCode() threw a NullPointerException for a name containing an RDN decoded from an empty SET, which any peer can encode, and was marking the value calculated before computing it, so once a style had thrown every later call quietly returned 0.
  • HSSSigner.init and LMSSigner.init assigned only the key for the mode being set, so a signer initialised for verification still held the private key from an earlier signing init and would sign with it. Both keys are now cleared on every init.
  • XMSSSigner.init and XMSSMTSigner.init assigned only the key for the mode being set, and verifySignature carried no mode check, so a signer re-initialised for signing still verified against the public key left by an earlier verification init – and returned true rather than failing.
  • The multi-release overlay copies of the EdEC provider SPIs had drifted from the base implementations: on JDK 11+ the XDH KeyAgreement ignored the UserKeyingMaterialSpec salt and the org.bouncycastle.emulate.oracle property, and on JDK 11+/15+ keys from third-party providers exposing only their encoding were rejected. The SPIs now exist once, in the base tree, with version-specific key construction and conversion in the multi-release XDHKeys and EdDSAKeys hook classes.
  • KeyStore.getCertificateAlias on a PKCS12 keystore could return the alias of an unrelated certificate: the alias and certificate enumerations were paired positionally, but keys() enumerates a copy whose order can diverge from the live table’s once enough entries are present (github #2384).
  • The RFC 5280 sec. 4.1.2.4 check rejecting certificates whose issuer is an empty distinguished name had no opt-out, breaking parsing of the non-PKIX self-signed identity certificates used by the libp2p TLS profile. Setting org.bouncycastle.x509.allow_empty_issuer_cert to “true” now relaxes the certificate parse path; generation and X509CertificateReviewer stay strict (github #2387).