Legacy TLS
Why it is hard
Section titled “Why it is hard”The Sejong portal offers only one cipher on TLS 1.2: TLS_RSA_WITH_AES_256_CBC_SHA (OpenSSL name AES256-SHA). It is an old construction, and current JDK and OpenSSL defaults switch it off. An HTTPS client with default settings therefore fails at the handshake and never reaches the login form.
What the library does
Section titled “What the library does”Each language solves it in its own way.
| Language | Method | Scope |
|---|---|---|
| Python | Set the cipher list of the ssl context to DEFAULT:AES256-SHA:@SECLEVEL=1 |
This library’s connections only |
| Node.js | https.Agent({ ciphers: 'DEFAULT:AES256-SHA:@SECLEVEL=1' }) |
This library’s connections only |
| Java | Remove TLS_RSA_* from jdk.tls.disabledAlgorithms |
The whole JVM |
- With OpenSSL 3.x, Python and Node.js must add this cipher to the list explicitly and lower the security level to
1to use it. @SECLEVEL=1is kept on purpose: level 0 would also accept weak certificate keys.- Certificate verification stays on by default (Configuration).
The Java catch
Section titled “The Java catch”JSSE reads this security property once, at the JVM’s first TLS use. Changing it later has no effect.
- Spring Boot:
SejongTlsEnvironmentPostProcessorhandles it automatically at startup. - Plain Java: call
SejongTlsSupport.ensureLegacyCipherEnabled()first inmain(). If another HTTPS call happens first, it is too late. - Calling it too late fails with
CONNECTION_FAILED, and the message names the cause and the fix. - The change applies to the whole JVM, so other code in the same process may use this cipher too. If that is not acceptable, run authentication in a separate process.
public static void main(String[] args) { SejongTlsSupport.ensureLegacyCipherEnabled(); // before any other HTTPS call // ... start the app}- Source table: Transport requirements in spec/PORTAL_FLOW.md
- The next barrier: Firewall and User-Agent
