레거시 TLS
왜 어려운가
섹션 제목: “왜 어려운가”세종 포털은 TLS 1.2에서 암호 TLS_RSA_WITH_AES_256_CBC_SHA(OpenSSL 이름 AES256-SHA) 하나만 제안합니다. 이 암호는 오래된 방식이라 최근 JDK와 OpenSSL의 기본 설정이 꺼 둡니다. 그래서 아무 설정 없이 HTTPS 클라이언트를 만들면 연결 단계(handshake)에서 실패하고, 로그인 폼까지 가지도 못합니다.
라이브러리가 하는 일
섹션 제목: “라이브러리가 하는 일”언어마다 푸는 방식이 다릅니다.
| 언어 | 방식 | 범위 |
|---|---|---|
| Python | ssl 컨텍스트의 암호 목록을 DEFAULT:AES256-SHA:@SECLEVEL=1로 설정 |
이 라이브러리의 연결만 |
| Node.js | https.Agent({ ciphers: 'DEFAULT:AES256-SHA:@SECLEVEL=1' }) |
이 라이브러리의 연결만 |
| Java | jdk.tls.disabledAlgorithms에서 TLS_RSA_* 제거 |
JVM 전체 |
- Python과 Node.js는 OpenSSL 3.x에서 이 암호를 쓰려면 목록에 직접 추가하고 보안 레벨을
1로 내려야 합니다. @SECLEVEL=1을 유지하는 이유: 레벨 0으로 낮추면 약한 인증서 키까지 받아들이기 때문입니다.- 인증서 검증은 기본으로 켜져 있습니다 (설정).
Java에서 특히 조심할 점
섹션 제목: “Java에서 특히 조심할 점”JSSE는 이 보안 속성을 JVM이 처음 TLS를 쓸 때 한 번만 읽습니다. 그 뒤에 바꿔도 효과가 없습니다.
- Spring Boot: 시작할 때
SejongTlsEnvironmentPostProcessor가 자동으로 처리합니다. - 일반 Java:
main()맨 앞에서SejongTlsSupport.ensureLegacyCipherEnabled()를 부르세요. 다른 HTTPS 호출이 먼저 일어나면 늦습니다. - 너무 늦게 부르면
CONNECTION_FAILED로 실패하고, 메시지에 원인과 해결 방법이 같이 나옵니다. - 이 변경은 JVM 전체에 적용되어 같은 프로세스의 다른 코드도 이 암호를 쓸 수 있게 됩니다. 허용할 수 없다면 인증을 별도 프로세스로 분리하세요.
public static void main(String[] args) { SejongTlsSupport.ensureLegacyCipherEnabled(); // 다른 HTTPS 호출보다 먼저 // ... 이후 앱 시작}이어서 보기
섹션 제목: “이어서 보기”- 원본 표: spec/PORTAL_FLOW.md의 Transport requirements
- 다음 장벽: 방화벽과 User-Agent
