Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Last active June 4, 2025 04:41
Show Gist options
  • Save ArrayIterator/9b362503a62145a08a46782e28c991c3 to your computer and use it in GitHub Desktop.
Save ArrayIterator/9b362503a62145a08a46782e28c991c3 to your computer and use it in GitHub Desktop.

Revisions

  1. ArrayIterator revised this gist Jun 4, 2025. 1 changed file with 290 additions and 225 deletions.
    515 changes: 290 additions & 225 deletions CipherSuite.java
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;

    @@ -123,6 +122,7 @@ public class CipherSuite {
    public final static int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; // Not a real cipher, but a signaling value

    // --- Protocol Versions ---
    public final static long TLS_UNKNOWN = 0x0000; // Unknown or not specified
    public final static long SSL3_0 = 0x0300;
    public final static long TLS1_0 = 0x0301;
    public final static long TLS1_1 = 0x0302;
    @@ -141,221 +141,252 @@ public class CipherSuite {
    */
    private final int id;

    // --- Sets of cipher suite IDs supported by different protocol versions ---
    // Using Set for efficient lookup (contains method)
    // Populated based on common standards and RFCs.
    // Note: Some cipher suites might be technically supported but considered weak/deprecated in later versions.
    // This represents 'protocol level' support.
    private static final Set<Integer> v3;
    private static final Set<Integer> V1_0;
    private static final Set<Integer> V1_1;
    private static final Set<Integer> V1_2;
    private static final Set<Integer> V1_3;

    // --- Comprehensive Map from ID to Name ---
    private static final Map<Integer, String> CIPHER_SUITE_ID_TO_NAME_MAP;

    // Static initializer block to populate the map and version sets once
    static {
    CIPHER_SUITE_ID_TO_NAME_MAP = Map.<Integer, String>ofEntries(
    Map.entry(TLS_NULL_WITH_NULL_NULL, "TLS_NULL_WITH_NULL_NULL"),
    Map.entry(TLS_RSA_WITH_NULL_MD5, "TLS_RSA_WITH_NULL_MD5"),
    Map.entry(TLS_RSA_WITH_NULL_SHA, "TLS_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC4_40_MD5, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_MD5, "TLS_RSA_WITH_RC4_128_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA, "TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_RC4_128_SHA, "TLS_DHE_DSS_WITH_RC4_128_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
    Map.entry(TLS_RSA_WITH_IDEA_CBC_SHA, "TLS_RSA_WITH_IDEA_CBC_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_DES_CBC_SHA, "TLS_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_DES_CBC_SHA, "TLS_DHE_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS_DHE_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_DES_CBC_SHA, "TLS_DH_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_DES_CBC_SHA, "TLS_DH_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_128_CBC_SHA, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_CBC_SHA, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_256_CBC_SHA, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_CBC_SHA, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS_ECDH_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_NULL_SHA, "TLS_ECDH_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS_ECDH_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS_ECDHE_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"), // TLS 1.3
    Map.entry(TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_SHA256, "TLS_AES_128_CCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_8_SHA256, "TLS_AES_128_CCM_8_SHA256"), // TLS 1.3
    Map.entry(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
    );

    // SSL 3.0 supported cipher suites (often overlaps heavily with TLS 1.0)
    v3 = Set.of(
    TLS_NULL_WITH_NULL_NULL,
    TLS_RSA_WITH_NULL_MD5,
    TLS_RSA_WITH_NULL_SHA,
    TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    TLS_RSA_WITH_RC4_128_MD5,
    TLS_RSA_WITH_RC4_128_SHA,
    TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    TLS_RSA_WITH_IDEA_CBC_SHA,
    TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_RSA_WITH_DES_CBC_SHA,
    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_DSS_WITH_DES_CBC_SHA,
    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_RSA_WITH_DES_CBC_SHA,
    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_DSS_WITH_DES_CBC_SHA,
    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_RSA_WITH_DES_CBC_SHA,
    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
    );

    // TLS 1.0 supported cipher suites (initially the same as SSL 3.0, but SSL 3.0 is deprecated)
    V1_0 = new HashSet<>(v3); // Starts with SSL 3.0 ciphers

    // TLS 1.1 supported cipher suites (largely the same as TLS 1.0)
    V1_1 = new HashSet<>(V1_0); // Starts with TLS 1.0 ciphers

    // TLS 1.2 supported cipher suites
    // Adds stronger AES-CBC and AES-GCM suites, and ECDHE suites.
    V1_2 = new HashSet<>(V1_1); // Start with previous version ciphers
    V1_2.addAll(Set.of(
    // AES CBC ciphers
    TLS_RSA_WITH_AES_128_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_DH_DSS_WITH_AES_128_CBC_SHA,
    TLS_DH_RSA_WITH_AES_128_CBC_SHA,
    TLS_RSA_WITH_AES_256_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_DH_DSS_WITH_AES_256_CBC_SHA,
    TLS_DH_RSA_WITH_AES_256_CBC_SHA,
    TLS_RSA_WITH_AES_128_CBC_SHA256,
    TLS_RSA_WITH_AES_256_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,

    // AES GCM ciphers (officially for TLS 1.2 and later)
    TLS_RSA_WITH_AES_128_GCM_SHA256,
    TLS_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,

    // ECDHE/ECDH ciphers (integrated from RFC 4492)
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDH_RSA_WITH_NULL_SHA,
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_RSA_WITH_NULL_SHA,
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,

    // ChaCha20-Poly1305 (RFC 7905, often supported in TLS 1.2+)
    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    ));

    // TLS 1.3 supported cipher suites
    // TLS 1.3 uses a fundamentally different approach for cipher suites,
    // and only a few AEAD ciphers are defined.
    V1_3 = Set.of(
    TLS_AES_128_GCM_SHA256,
    TLS_AES_256_GCM_SHA384,
    TLS_CHACHA20_POLY1305_SHA256,
    TLS_AES_128_CCM_SHA256,
    TLS_AES_128_CCM_8_SHA256
    );
    }
    /**
    * List of protocol versions that support this cipher suite v3
    */
    private static final Set<Integer> SSLV3_CIPHER_SUITES = Set.of(
    TLS_NULL_WITH_NULL_NULL,
    TLS_RSA_WITH_NULL_MD5,
    TLS_RSA_WITH_NULL_SHA,
    TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    TLS_RSA_WITH_RC4_128_MD5,
    TLS_RSA_WITH_RC4_128_SHA,
    TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    TLS_RSA_WITH_IDEA_CBC_SHA,
    TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_RSA_WITH_DES_CBC_SHA,
    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_DSS_WITH_DES_CBC_SHA,
    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_RSA_WITH_DES_CBC_SHA,
    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_DSS_WITH_DES_CBC_SHA,
    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_RSA_WITH_DES_CBC_SHA,
    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
    );

    /**
    * List of cipher suites supported by TLS 1.0.
    * TLS 1.0 supports all SSL 3.0 cipher suites and adds DHE_DSS_WITH_RC4_128_SHA.
    */
    private static final Set<Integer> TLS1_0_CIPHER_SUITES = Set.of(
    TLS_NULL_WITH_NULL_NULL,
    TLS_RSA_WITH_NULL_MD5,
    TLS_RSA_WITH_NULL_SHA,
    TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    TLS_RSA_WITH_RC4_128_MD5,
    TLS_RSA_WITH_RC4_128_SHA,
    TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    TLS_RSA_WITH_IDEA_CBC_SHA,
    TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_RSA_WITH_DES_CBC_SHA,
    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_DSS_WITH_DES_CBC_SHA,
    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_RSA_WITH_DES_CBC_SHA,
    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_DSS_WITH_DES_CBC_SHA,
    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_RSA_WITH_DES_CBC_SHA,
    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_DSS_WITH_RC4_128_SHA
    );

    /**
    * List of protocol versions that support this cipher suite v1.1
    */
    private static final Set<Integer> TLS1_1_CIPHER_SUITES = TLS1_0_CIPHER_SUITES;

    /**
    * List of protocol versions that support this cipher suite v1.2
    */
    private static final Set<Integer> TLS1_2_CIPHER_SUITES = Set.of(
    // AES CBC ciphers
    TLS_RSA_WITH_AES_128_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_DH_DSS_WITH_AES_128_CBC_SHA,
    TLS_DH_RSA_WITH_AES_128_CBC_SHA,
    TLS_RSA_WITH_AES_256_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_DH_DSS_WITH_AES_256_CBC_SHA,
    TLS_DH_RSA_WITH_AES_256_CBC_SHA,
    TLS_RSA_WITH_AES_128_CBC_SHA256,
    TLS_RSA_WITH_AES_256_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,

    // AES GCM ciphers (officially for TLS 1.2 and later)
    TLS_RSA_WITH_AES_128_GCM_SHA256,
    TLS_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,

    // ECDHE/ECDH ciphers (integrated from RFC 4492)
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDH_RSA_WITH_NULL_SHA,
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_RSA_WITH_NULL_SHA,
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,

    // ChaCha20-Poly1305 (RFC 7905, often supported in TLS 1.2+)
    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    );

    /**
    * List of protocol versions that support this cipher suite v1.3
    */
    private static final Set<Integer> TLS1_3_CIPHER_SUITES = Set.of(
    TLS_AES_128_GCM_SHA256,
    TLS_AES_256_GCM_SHA384,
    TLS_CHACHA20_POLY1305_SHA256,
    TLS_AES_128_CCM_SHA256,
    TLS_AES_128_CCM_8_SHA256
    );

    /**
    * A map of protocol version IDs to their human-readable names.
    * This is used to provide a more user-friendly representation of the protocol versions.
    */
    private static final Map<Long, String> namedVersions = Map.of(
    SSL3_0, "SSLv3",
    TLS1_0, "TLSv1.0",
    TLS1_1, "TLSv1.1",
    TLS1_2, "TLSv1.2",
    TLS1_3, "TLSv1.3"
    );

    /**
    * A map of cipher suite IDs to their human-readable names.
    * This is used to provide a more user-friendly representation of the cipher suites.
    */
    private static final Map<Integer, String> CIPHER_SUITE_ID_TO_NAME_MAP = Map.<Integer, String>ofEntries(
    Map.entry(TLS_NULL_WITH_NULL_NULL, "TLS_NULL_WITH_NULL_NULL"),
    Map.entry(TLS_RSA_WITH_NULL_MD5, "TLS_RSA_WITH_NULL_MD5"),
    Map.entry(TLS_RSA_WITH_NULL_SHA, "TLS_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC4_40_MD5, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_MD5, "TLS_RSA_WITH_RC4_128_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA, "TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_RC4_128_SHA, "TLS_DHE_DSS_WITH_RC4_128_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
    Map.entry(TLS_RSA_WITH_IDEA_CBC_SHA, "TLS_RSA_WITH_IDEA_CBC_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_DES_CBC_SHA, "TLS_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_DES_CBC_SHA, "TLS_DHE_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS_DHE_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_DES_CBC_SHA, "TLS_DH_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_DES_CBC_SHA, "TLS_DH_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_128_CBC_SHA, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_CBC_SHA, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_256_CBC_SHA, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_CBC_SHA, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS_ECDH_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_NULL_SHA, "TLS_ECDH_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS_ECDH_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS_ECDHE_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"), // TLS 1.3
    Map.entry(TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_SHA256, "TLS_AES_128_CCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_8_SHA256, "TLS_AES_128_CCM_8_SHA256"), // TLS 1.3
    Map.entry(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
    );

    /**
    * Constructs a CipherSuite instance with the provided ID.
    @@ -375,14 +406,25 @@ public CipherSuite(int id) {
    * @return true if the cipher suite is supported by the version, false otherwise.
    */
    public boolean isSupported(long version) {
    return switch ((int) version) {
    case (int) SSL3_0 -> v3.contains(this.id);
    case (int) TLS1_0 -> V1_0.contains(this.id);
    case (int) TLS1_1 -> V1_1.contains(this.id);
    case (int) TLS1_2 -> V1_2.contains(this.id);
    case (int) TLS1_3 -> V1_3.contains(this.id);
    default -> false; // Version not recognized or no specific support defined
    };
    if (!namedVersions.containsKey(version)) {
    return false; // Version not recognized
    }
    if (version == TLS1_0) {
    return TLS1_0_CIPHER_SUITES.contains(this.id);
    }
    if (version == TLS1_1) {
    return TLS1_1_CIPHER_SUITES.contains(this.id);
    }
    if (version == TLS1_2) {
    return TLS1_2_CIPHER_SUITES.contains(this.id);
    }
    if (version == TLS1_3) {
    return TLS1_3_CIPHER_SUITES.contains(this.id);
    }
    if (version == SSL3_0) {
    return SSLV3_CIPHER_SUITES.contains(this.id);
    }
    return false; // Unsupported version
    }

    /**
    @@ -391,6 +433,7 @@ public boolean isSupported(long version) {
    *
    * @return The name of the cipher suite.
    */
    @Nullable
    public String getName() {
    return name;
    }
    @@ -405,6 +448,28 @@ public int getId() {
    return id;
    }

    /**
    * Gets the name of the cipher suite by its ID.
    * This method looks up the cipher suite name based on its unique identifier.
    *
    * @param id The unique identifier for the cipher suite.
    * @return The name of the cipher suite, or null if not found.
    */
    public static String getNameById(int id) {
    return CIPHER_SUITE_ID_TO_NAME_MAP.getOrDefault(id, null);
    }

    /**
    * Gets the human-readable name of a protocol version by its ID.
    * This method provides a user-friendly representation of the protocol version.
    *
    * @param version The protocol version ID (e.g., CipherSuite.TLS1_2).
    * @return The name of the protocol version, or null if not recognized.
    */
    public static String getNamedVersion(long version) {
    return namedVersions.getOrDefault(version, null);
    }

    /**
    * Factory method to create a CipherSuite instance from an ID.
    * This method is a convenience method to instantiate a CipherSuite with the given ID.
    @@ -415,4 +480,4 @@ public int getId() {
    public static CipherSuite fromId(int id) {
    return new CipherSuite(id);
    }
    }
    }
  2. ArrayIterator created this gist Jun 4, 2025.
    418 changes: 418 additions & 0 deletions CipherSuite.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,418 @@
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;

    /**
    * Represents a cipher suite in SSL/TLS.
    * A cipher suite is a combination of cryptographic algorithms used to secure the communication.
    * This class aims to provide a comprehensive (though not exhaustive) list of standard
    * cipher suites and their support across different SSL/TLS protocol versions.
    */
    public class CipherSuite {

    // --- Standard Cipher Suite IDs (Common and Historically Significant) ---
    // (This list is extensive but still not absolutely exhaustive. Refer to RFCs for full details.)

    // NULL Ciphers (No Encryption/Authentication)
    public final static int TLS_NULL_WITH_NULL_NULL = 0x0000;
    public final static int TLS_RSA_WITH_NULL_MD5 = 0x0001;
    public final static int TLS_RSA_WITH_NULL_SHA = 0x0002;

    // RC4 Ciphers
    public final static int TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003;
    public final static int TLS_RSA_WITH_RC4_128_MD5 = 0x0004;
    public final static int TLS_RSA_WITH_RC4_128_SHA = 0x0005;
    public final static int TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA = 0x0017;
    public final static int TLS_DHE_DSS_WITH_RC4_128_SHA = 0x0018;

    // RC2 Ciphers
    public final static int TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006;

    // IDEA Ciphers
    public final static int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007;

    // DES/3DES Ciphers
    public final static int TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008;
    public final static int TLS_RSA_WITH_DES_CBC_SHA = 0x0009;
    public final static int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
    public final static int TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011;
    public final static int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012;
    public final static int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013;
    public final static int TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x001A;
    public final static int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x001B;
    public final static int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x001C;
    public final static int TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0014;
    public final static int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x0015;
    public final static int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0016;
    public final static int TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x001D;
    public final static int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x001E;
    public final static int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x001F;

    // AES CBC Ciphers (introduced in TLS 1.2, but some older versions might have non-standard support)
    public final static int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F;
    public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032;
    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033;
    public final static int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030;
    public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031;
    public final static int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
    public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038;
    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039;
    public final static int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036;
    public final static int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037;
    public final static int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; // TLS 1.2+
    public final static int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; // TLS 1.2+
    public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040; // TLS 1.2+
    public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x003F; // TLS 1.2+
    public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A; // TLS 1.2+
    public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; // TLS 1.2+

    // AES GCM Ciphers (TLS 1.2 and TLS 1.3)
    public final static int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; // TLS 1.2 only
    public final static int TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; // TLS 1.2 only
    public final static int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; // TLS 1.2 only
    public final static int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F; // TLS 1.2 only
    public final static int TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0; // TLS 1.2 only
    public final static int TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1; // TLS 1.2 only
    public final static int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; // TLS 1.2 only
    public final static int TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3; // TLS 1.2 only

    // ECDHE Ciphers (RFC 4492, then integrated into TLS 1.2)
    public final static int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC006;
    public final static int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC007;
    public final static int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008;
    public final static int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC009;
    public final static int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
    public final static int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC00B;
    public final static int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC00C;
    public final static int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC00D;
    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC00E;
    public final static int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00F;
    public final static int TLS_ECDH_RSA_WITH_NULL_SHA = 0xC010;
    public final static int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC011;
    public final static int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012;
    public final static int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC013;
    public final static int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC014;
    public final static int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC015;
    public final static int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC016;
    public final static int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC017;
    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC018;
    public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC019;
    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023; // TLS 1.2+
    public final static int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024; // TLS 1.2+
    public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027; // TLS 1.2+
    public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028; // TLS 1.2+
    public final static int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; // TLS 1.2 only
    public final static int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; // TLS 1.2 only
    public final static int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; // TLS 1.2 only
    public final static int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; // TLS 1.2 only

    // CHACHA20-POLY1305 Ciphers (RFC 7905, TLS 1.2 mostly, but also TLS 1.3)
    public final static int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; // TLS 1.2 only
    public final static int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; // TLS 1.2 only

    // TLS 1.3 Specific Ciphers (RFC 8446)
    // Note: TLS 1.3 simplified cipher suites, they are now identified differently (e.g., KEM, cipher, HKDF hash)
    // The following are the *only* 5 standard cipher suites for TLS 1.3.
    public final static int TLS_AES_128_GCM_SHA256 = 0x1301;
    public final static int TLS_AES_256_GCM_SHA384 = 0x1302;
    public final static int TLS_CHACHA20_POLY1305_SHA256 = 0x1303;
    public final static int TLS_AES_128_CCM_SHA256 = 0x1304;
    public final static int TLS_AES_128_CCM_8_SHA256 = 0x1305;

    // Placeholder for SCSV (Signaling Cipher Suite Value)
    public final static int TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; // Not a real cipher, but a signaling value

    // --- Protocol Versions ---
    public final static long SSL3_0 = 0x0300;
    public final static long TLS1_0 = 0x0301;
    public final static long TLS1_1 = 0x0302;
    public final static long TLS1_2 = 0x0303;
    public final static long TLS1_3 = 0x0304;

    /**
    * The name of the cipher suite.
    * This is a human-readable string representation of the cipher suite.
    */
    private final String name;

    /**
    * The ID of the cipher suite.
    * This is a unique identifier for the cipher suite.
    */
    private final int id;

    // --- Sets of cipher suite IDs supported by different protocol versions ---
    // Using Set for efficient lookup (contains method)
    // Populated based on common standards and RFCs.
    // Note: Some cipher suites might be technically supported but considered weak/deprecated in later versions.
    // This represents 'protocol level' support.
    private static final Set<Integer> v3;
    private static final Set<Integer> V1_0;
    private static final Set<Integer> V1_1;
    private static final Set<Integer> V1_2;
    private static final Set<Integer> V1_3;

    // --- Comprehensive Map from ID to Name ---
    private static final Map<Integer, String> CIPHER_SUITE_ID_TO_NAME_MAP;

    // Static initializer block to populate the map and version sets once
    static {
    CIPHER_SUITE_ID_TO_NAME_MAP = Map.<Integer, String>ofEntries(
    Map.entry(TLS_NULL_WITH_NULL_NULL, "TLS_NULL_WITH_NULL_NULL"),
    Map.entry(TLS_RSA_WITH_NULL_MD5, "TLS_RSA_WITH_NULL_MD5"),
    Map.entry(TLS_RSA_WITH_NULL_SHA, "TLS_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC4_40_MD5, "TLS_RSA_EXPORT_WITH_RC4_40_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_MD5, "TLS_RSA_WITH_RC4_128_MD5"),
    Map.entry(TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA, "TLS_DHE_DSS_EXPORT_WITH_RC4_40_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_RC4_128_SHA, "TLS_DHE_DSS_WITH_RC4_128_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
    Map.entry(TLS_RSA_WITH_IDEA_CBC_SHA, "TLS_RSA_WITH_IDEA_CBC_SHA"),
    Map.entry(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_DES_CBC_SHA, "TLS_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_DES_CBC_SHA, "TLS_DHE_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS_DHE_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_DES_CBC_SHA, "TLS_DH_DSS_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_DES_CBC_SHA, "TLS_DH_RSA_WITH_DES_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_128_CBC_SHA, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_CBC_SHA, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_DSS_WITH_AES_256_CBC_SHA, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_CBC_SHA, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS_ECDH_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_NULL_SHA, "TLS_ECDH_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS_ECDH_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS_ECDHE_RSA_WITH_NULL_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"),
    Map.entry(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"),
    Map.entry(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"),
    Map.entry(TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"), // TLS 1.3
    Map.entry(TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_SHA256, "TLS_AES_128_CCM_SHA256"), // TLS 1.3
    Map.entry(TLS_AES_128_CCM_8_SHA256, "TLS_AES_128_CCM_8_SHA256"), // TLS 1.3
    Map.entry(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV")
    );

    // SSL 3.0 supported cipher suites (often overlaps heavily with TLS 1.0)
    v3 = Set.of(
    TLS_NULL_WITH_NULL_NULL,
    TLS_RSA_WITH_NULL_MD5,
    TLS_RSA_WITH_NULL_SHA,
    TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    TLS_RSA_WITH_RC4_128_MD5,
    TLS_RSA_WITH_RC4_128_SHA,
    TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    TLS_RSA_WITH_IDEA_CBC_SHA,
    TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_RSA_WITH_DES_CBC_SHA,
    TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_DSS_WITH_DES_CBC_SHA,
    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DHE_RSA_WITH_DES_CBC_SHA,
    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_DSS_WITH_DES_CBC_SHA,
    TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
    TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TLS_DH_RSA_WITH_DES_CBC_SHA,
    TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
    );

    // TLS 1.0 supported cipher suites (initially the same as SSL 3.0, but SSL 3.0 is deprecated)
    V1_0 = new HashSet<>(v3); // Starts with SSL 3.0 ciphers

    // TLS 1.1 supported cipher suites (largely the same as TLS 1.0)
    V1_1 = new HashSet<>(V1_0); // Starts with TLS 1.0 ciphers

    // TLS 1.2 supported cipher suites
    // Adds stronger AES-CBC and AES-GCM suites, and ECDHE suites.
    V1_2 = new HashSet<>(V1_1); // Start with previous version ciphers
    V1_2.addAll(Set.of(
    // AES CBC ciphers
    TLS_RSA_WITH_AES_128_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_DH_DSS_WITH_AES_128_CBC_SHA,
    TLS_DH_RSA_WITH_AES_128_CBC_SHA,
    TLS_RSA_WITH_AES_256_CBC_SHA,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_DH_DSS_WITH_AES_256_CBC_SHA,
    TLS_DH_RSA_WITH_AES_256_CBC_SHA,
    TLS_RSA_WITH_AES_128_CBC_SHA256,
    TLS_RSA_WITH_AES_256_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,

    // AES GCM ciphers (officially for TLS 1.2 and later)
    TLS_RSA_WITH_AES_128_GCM_SHA256,
    TLS_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
    TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
    TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
    TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,

    // ECDHE/ECDH ciphers (integrated from RFC 4492)
    TLS_ECDH_ECDSA_WITH_NULL_SHA,
    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    TLS_ECDH_RSA_WITH_NULL_SHA,
    TLS_ECDH_RSA_WITH_RC4_128_SHA,
    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_RSA_WITH_NULL_SHA,
    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,

    // ChaCha20-Poly1305 (RFC 7905, often supported in TLS 1.2+)
    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    ));

    // TLS 1.3 supported cipher suites
    // TLS 1.3 uses a fundamentally different approach for cipher suites,
    // and only a few AEAD ciphers are defined.
    V1_3 = Set.of(
    TLS_AES_128_GCM_SHA256,
    TLS_AES_256_GCM_SHA384,
    TLS_CHACHA20_POLY1305_SHA256,
    TLS_AES_128_CCM_SHA256,
    TLS_AES_128_CCM_8_SHA256
    );
    }

    /**
    * Constructs a CipherSuite instance with the provided ID.
    * This constructor initializes the cipher suite name based on the ID.
    *
    * @param id The unique identifier for the cipher suite.
    */
    public CipherSuite(int id) {
    this.id = id;
    this.name = CIPHER_SUITE_ID_TO_NAME_MAP.getOrDefault(id, null);
    }

    /**
    * Checks if this cipher suite is supported by the given SSL/TLS protocol version.
    *
    * @param version The SSL/TLS protocol version (e.g., CipherSuite.TLS1_2).
    * @return true if the cipher suite is supported by the version, false otherwise.
    */
    public boolean isSupported(long version) {
    return switch ((int) version) {
    case (int) SSL3_0 -> v3.contains(this.id);
    case (int) TLS1_0 -> V1_0.contains(this.id);
    case (int) TLS1_1 -> V1_1.contains(this.id);
    case (int) TLS1_2 -> V1_2.contains(this.id);
    case (int) TLS1_3 -> V1_3.contains(this.id);
    default -> false; // Version not recognized or no specific support defined
    };
    }

    /**
    * Gets the name of the cipher suite.
    * This method returns the human-readable string representation of the cipher suite.
    *
    * @return The name of the cipher suite.
    */
    public String getName() {
    return name;
    }

    /**
    * Gets the ID of the cipher suite.
    * This method returns the unique identifier for the cipher suite.
    *
    * @return The ID of the cipher suite.
    */
    public int getId() {
    return id;
    }

    /**
    * Factory method to create a CipherSuite instance from an ID.
    * This method is a convenience method to instantiate a CipherSuite with the given ID.
    *
    * @param id The unique identifier for the cipher suite.
    * @return A new CipherSuite instance with the specified ID.
    */
    public static CipherSuite fromId(int id) {
    return new CipherSuite(id);
    }
    }