Bouncy Castle Java

repository·main·Indexed 25 days ago

https://github.com/bcgit/bc-java

A comprehensive Java implementation of cryptographic algorithms providing a lightweight API and a full JCA/JCE provider. The project includes modules for core crypto, PKIX, S/MIME, OpenPGP, and TLS, as well as a specialized bctls-klog extension for RFC 9850 key logging.

Tokens
14.4K
Snippets
24
Records
69
Agent score
83%

What's inside Bouncy Castle Java

  1. Overview of bctls-klog (RFC 9850 Key Logging)

    main

    bctls-klog is a specialized Bouncy Castle TLS API designed for RFC 9850 (SSLKEYLOGFILE) key logging. It allows you to report TLS connection secrets so that packet captures (e.g., from Wireshark) can be decrypted for analysis.

    CRITICAL WARNING: DO NOT USE IN PRODUCTION. RFC 9850 specifies that this mechanism MUST NOT be used in production systems. Anyone with access to these secrets can decrypt the associated traffic. Treat the bctls-klog JAR as a security risk that can expose every TLS connection made by the JVM.

  2. Understand the Bouncy Castle Module Graph

    main

    The project is organized into several modules with specific dependencies. Understanding this graph is crucial for knowing where specific cryptographic APIs reside and how they relate to the JCA/JCE provider:

    • core: Lightweight crypto API (engines, digests, ASN.1, math, params).
    • util: ASN.1/X.500 helpers used by pkix.
    • prov: JCA/JCE provider (BouncyCastleProvider, BouncyCastlePQCProvider). Depends on core.
    • pkix: X.509 / CMS / TSP / OCSP / PKCS#12 / OpenSSL PEM. Depends on prov.
    • pg: OpenPGP. Depends on prov.
    • tls: TLS API + JSSE provider. Depends on prov.
    • mail / jmail: S/MIME on top of CMS. Depends on pkix.
    • mls: Messaging Layer Security.

    Note on prov and core: The bcprov-<vmrange>.jar contains both the core lightweight API and the prov JCE provider classes because prov/build.gradle includes core/src/main/java directly in its source directories.

  3. Understand Bouncy Castle module organization

    main

    The project is organized into several functional modules:

    • core: Provides all lightweight API functionality.
    • prov: Provides JCA/JCE provider functionality.
    • util: Contains shared code, primarily ASN.1 classes for the PKIX module.
    • pkix: Handles X.509 certificate generation and APIs for standards relying on ASN.1 (CMS, TSP, PKCS#12, OCSP, CRMF, and CMP).
    • mail: Provides an S/MIME API built on top of CMS.
    • pg: Supports OpenPGP.
    • tls: Provides a general TLS API and JSSE Provider.

    Warning for JCE users: If you are using a JDK version that already includes a JCE install (JDK 1.4+), do not include the jce/src/main/java directory as a source file, as it will clash with the JCE API provided by your JDK.

  4. Follow Bouncy Castle code style and brace conventions

    main

    The project uses Allman braces and 4-space indentation (no tabs). Brace placement is machine-enforced via the Gradle checkstyle plugin.

    Brace Rules:

    • Left Curly ({): Must be on its own new line (option="nl"). This applies to classes, methods, control structures (if, for, while, try, switch), and lambda bodies.
    • Right Curly (}): Must be alone on its own line (option="alone").

    Validation: Run the following command to check for violations locally before pushing:

    ./gradlew checkstyleMain

    Violations will result in a build failure in CI.

  5. Implement a new PQC algorithm (Checklist)

    main

    When adding a new PQC algorithm, you must implement it across both the lightweight core and the JCE-facing prov modules. Follow this checklist:

    1. Core/Lightweight Layer (core/):

    • OIDs: Add the OID to core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java (or NISTObjectIdentifiers.java).
    • Engine: Implement lightweight classes in core/src/main/java/org/bouncycastle/pqc/crypto/<alg>/ (e.g., *Parameters, *PublicKeyParameters, *KeyPairGenerator, *Signer).
    • Utilities: Implement maps and lookups in core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java and register converters in PublicKeyFactory.java and PrivateKeyFactory.java.
    • Factories: Update SubjectPublicKeyInfoFactory.java and PrivateKeyInfoFactory.java with instanceof branches for the new parameters.

    2. JCE/Provider Layer (prov/):

    • Spec: Create AlgorithmParameterSpec in prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/<Alg>ParameterSpec.java.
    • Key Interface: Implement <Alg>Key in prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/<Alg>Key.java.
    • SPI Implementation: Implement BC<Alg>PublicKey, BC<Alg>PrivateKey, <Alg>KeyFactorySpi, <Alg>KeyPairGeneratorSpi, and <Alg>SignatureSpi in prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/<alg>/.
    • Mappings: Create <Alg>.java in the provider package, extending AsymmetricAlgorithmProvider and calling addKeyFactoryAlgorithm, etc.
    • Provider Integration:
      • Add the algorithm name to ALGORITHMS in BouncyCastlePQCProvider.java.
      • Crucial: Register the converter in BouncyCastleProvider.java via loadPQCKeys() to bridge to the BC provider.
    • Module Info: Update module-info.java (both jdk1.9 and ext-jdk1.9 variants) to export the new packages.

    3. Testing & Documentation:

    • Add tests in prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/<Alg>Test.java.
    • Ensure tests exercise BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo) to verify the BC bridge works.
    • Add an entry to docs/releasenotes.html.
  6. Locate and use example code in the `misc/` module

    main

    Canonical example and demo code is located in the misc/ module, not within the primary Gradle modules (like core, prov, or pg).

    Key locations:

    • misc/src/main/java/org/bouncycastle/{asn1,crypto,jcajce,openpgp,pqc/crypto}/examples/

    Important Notes:

    • The misc module is a non-publishing module; its code is compiled and tested via ./gradlew :misc:build to ensure it remains compatible with the library, but it is not included in the published bc* JARs or Maven distributions.
    • If you are looking for examples of non-standard JCE aliases (e.g., Cipher.ECIESwithSHA256andAES-ECB), check the misc/ directory. Bouncy Castle typically does not register these non-standard aliases, so the examples demonstrate how to construct them locally using the lightweight API.
    ./gradlew :misc:build
  7. Build, sign, and test JDK 1.4 artifacts

    main

    To perform a full build, signing, and testing cycle for the JDK 1.4 distribution, follow these steps. Note that JRE 1.4 requires providers to be signed, or they will fail with a "provider BC may not be signed by a trusted party" error.

    Important: Always sign the jars after build-test because the test process may re-jar components and wipe existing signatures.

    Note on cleaning: The staging tree build/jdk1.4 and artifact trees are never cleaned by the build script. If you change excludes, delete overlays, or rename files, you must manually run rm -rf build before rebuilding to prevent stale sources from compiling.

  8. Add Bouncy Castle to a Maven project

    main

    To use the lightweight crypto API and the JCA/JCE providers, add the bcprov-jdk18on artifact to your pom.xml. This is the most common starting point and is required by all other Bouncy Castle modules.

    Note: The -jdk18on suffix indicates support for JDK 1.8 and newer. Do not use the older -jdk15on artifacts as they are end-of-life.

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk18on</artifactId>
        <version>1.84</version>
    </dependency>
  9. Understand the Bouncy Castle package layering strategy

    main

    Bouncy Castle uses a strict layering pattern to separate lightweight implementations from JCA/JCE (Java Cryptography Architecture) implementations. When working with or extending the library, you must choose the correct subpackage based on the dependencies required:

    • Top-level packages (e.g., org.bouncycastle.cms, org.bouncycastle.openpgp): These are high-level abstractions. They must be JCA-free and lightweight-free. They should only use interfaces (like DigestCalculatorProvider or ContentSigner) and must not import java.security.*, javax.crypto.*, or org.bouncycastle.crypto.* (except for java.security.SecureRandom).
    • .bc subpackages (e.g., org.bouncycastle.cms.bc): These contain lightweight implementations that directly use org.bouncycastle.crypto.* engines, signers, and digests.
    • .jcajce subpackages (e.g., org.bouncycastle.cms.jcajce): These contain JCA/JCE implementations that call java.security.* or javax.crypto.* classes (typically via JcaJceHelper).

    Decision Rule for adding code:

    • If a class needs java.security or javax.crypto (beyond SecureRandom): Use a .jcajce subpackage.
    • If a class needs org.bouncycastle.crypto.*: Use a .bc subpackage.
    • If a class is a high-level utility: Use a top-level package and pass in providers/operators as parameters instead of instantiating specific engines or JCA classes directly.
  10. Create JDK 1.3 overlays

    main

    The JDK 1.3 build layers overlays in this order: base src/main/java $\rightarrow$ src/main/jdk1.4 (overwrite) $\rightarrow$ src/main/jdk1.3 (overwrite).

    Crucial Rule: When creating a new JDK 1.3 overlay for a class, do not base it on src/main/java. Instead, base it on the existing JDK 1.4 overlay if one exists. Basing it on the base source re-introduces Java 5/1.4 APIs (like ConcurrentHashMap or Logger) that the 1.4 overlay had already removed, which will break the 1.3 build.

  11. Test PQC engines using public APIs and deterministic randomness

    main

    To prevent leaking internal engine implementations into the published API, keep <Alg>Engine classes package-private. Instead of testing the engine directly, drive Known Answer Tests (KATs) through the public <Alg>KeyPairGenerator or <Alg>Signer using deterministic randomness.

    Recommended Randomness Tools:

    • org.bouncycastle.util.test.FixedSecureRandom(bytes): Use for single-shot tests requiring a specific seed.
    • org.bouncycastle.pqc.crypto.test.NISTSecureRandom(seed, personalization): Use for NIST CTR-DRBG upstream KAT generators. A single instance can be reused across key generation and signing calls to reproduce reference implementation vectors byte-for-byte.

    Pattern: If you cannot demote an engine to package-private because tests depend on it, rewrite the tests to use the public API with NISTSecureRandom first, then demote the engine.

  12. Manage Multi-Release (MR) JAR overlays

    main

    Bouncy Castle modules (like prov, pkix, pg, tls) use Multi-Release JARs to provide version-specific implementations.

    Source Structure

    • src/main/java: Base sources (compiled with --release 8).
    • src/main/jdk1.9, src/main/jdk1.11, src/main/jdk1.15, src/main/jdk17, src/main/jdk25: Version-specific overlays.
    • src/main/j2me, src/main/jdk1.1 ... src/main/ext-jdk1.9: Legacy Ant distributions (not managed by Gradle).

    Critical Warning: Testing Overlays

    Standard tests in src/test/java do not execute the code in MR-jar overlays. If you modify a class that has a version-specific twin (e.g., in src/main/jdk1.11), you must manually add a test in the corresponding test directory (e.g., src/test/jdk1.11) and register it in the matching AllTests11 suite to ensure the overlay behavior is correct.