Cryptoramic

Server configuration

Hybrid key exchange in Go crypto/tls

Prefer a hybrid post-quantum key exchange group in Go crypto/tls.

Settings that make a server prefer a hybrid key exchange group. Group names differ by product, and hybrid groups need a TLS library that includes them (OpenSSL 3.5 or later, BoringSSL, Go 1.24 or later).

Prefer the hybrid group

cfg := &tls.Config{
    CurvePreferences: []tls.CurveID{tls.X25519MLKEM768, tls.X25519, tls.CurveP256},
}

Allow only post-quantum groups

cfg := &tls.Config{
    MinVersion:       tls.VersionTLS13,
    CurvePreferences: []tls.CurveID{tls.X25519MLKEM768},
}

Log the negotiated group

slog.Info("tls", "group", state.CurveID, "cipher", tls.CipherSuiteName(state.CipherSuite))

Notes for Go crypto/tls

The default list already includes X25519MLKEM768 from Go 1.24. Reading the negotiated group from the handshake state, ConnectionState.CurveID, needs Go 1.25. Go does not expose the client identity at the handshake, so log the remote address beside the group. Go has no native ML-KEM TLS group, so the list is the hybrid group alone.

Checked in a lab with Go 1.27 on Oct 18, 2026.

Other servers

nginx, Apache httpd, HAProxy, Envoy, OpenSSL, OpenSSH sshd, Java JSSE, IIS (Windows Schannel).

Back to perspectives

Find which of your servers still negotiate classical key exchange.

Discuss an assessment

Product screenshot

Illustrative assessment data