Java 애플리케이션에서 SQL Server에 연결하려는데 갑자기 SSL 관련 오류가 발생해서 당황하셨나요? 특히 기존에 잘 동작하던 시스템이 Java 버전을 업그레이드한 후 갑자기 작동하지 않는다면 더욱 답답하죠. 오늘은 이 문제의 원인과 해결 방법을 단계별로 완벽하게 정리해드립니다.
오류 메시지 전문
드라이버가 SSL(Secure Sockets Layer) 암호화를 사용하여 SQL Server로 보안 연결을 설정할 수 없습니다.
The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption.
또는
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption.
문제 발생 원인 – 왜 갑자기?
핵심 원인
Java 8 이상 버전부터 보안 정책이 강화되면서 MD5, SHA1 같은 약한 암호화 알고리즘이 기본적으로 비활성화되었습니다. 특히 SQL Server 2005, 2008 같은 구버전은 이러한 약한 알고리즘을 사용하기 때문에 Java의 보안 정책과 충돌이 발생합니다.
주요 발생 환경:
- Java 8 이상 버전 사용
- SQL Server 2005, 2008, 2012 구버전 사용
- JDBC 드라이버 버전이 낮은 경우
- 기존 Java 7에서 Java 8로 업그레이드한 경우
기술적 배경
Java 8부터 java.security 파일에 다음과 같은 제약이 추가되었습니다:
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024
이 설정 때문에 구버전 SQL Server와의 SSL 통신이 차단됩니다.
해결 방법 1 – Java 보안 정책 수정 (권장)
가장 확실하고 많이 사용되는 방법입니다. Java의 보안 정책 파일을 직접 수정합니다.
1단계: java.security 파일 위치 찾기
일반적인 경로:
# Oracle JDK
/usr/lib/jdk1.8.0_261/jre/lib/security/java.security
# OpenJDK
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-2.6.8.0.el7_3.x86_64/jre/lib/security/java.security
# Windows
C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\java.security
정확한 경로 확인 방법:
오류 메시지를 자세히 보면 다음과 같은 경로가 표시됩니다:
java.security path: /usr/lib/jdk1.8.0_261/jre/lib/security
이 경로가 실제 Java가 사용하는 보안 파일의 위치입니다.
또는 명령어로 확인:
# Linux
echo $JAVA_HOME
ls -la $JAVA_HOME/jre/lib/security/java.security
# 실행 중인 Java 경로 확인
ps -ef | grep java
2단계: 파일 백업 (중요!)
수정 전 반드시 원본을 백업하세요:
# Linux
sudo cp /usr/lib/jdk1.8.0_261/jre/lib/security/java.security /usr/lib/jdk1.8.0_261/jre/lib/security/java.security.backup
# Windows (관리자 권한 CMD)
copy "C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\java.security" "C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\java.security.backup"
3단계: java.security 파일 수정
Linux 환경:
# vi 에디터로 열기
sudo vi /usr/lib/jdk1.8.0_261/jre/lib/security/java.security
# 또는 nano 에디터
sudo nano /usr/lib/jdk1.8.0_261/jre/lib/security/java.security
Windows 환경:
관리자 권한으로 메모장을 실행한 후 파일 열기
4단계: 알고리즘 제약 완화
파일 내에서 다음 두 항목을 찾습니다 (Ctrl+F 또는 /키 사용):
수정 전:
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \\
DSA keySize < 1024, EC keySize < 224
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \\
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL
수정 후:
jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
핵심 변경사항:
MD5제거 (SQL Server 2005/2008 호환성)TLSv1,TLSv1.1제거 (구버전 TLS 허용)MD5withRSA제거DES제거- DH keySize를 1024에서 768로 완화
5단계: 애플리케이션 재시작
중요: 파일 수정 후 반드시 Java 애플리케이션을 재시작해야 적용됩니다.
# Tomcat 재시작 예시
sudo systemctl restart tomcat
# 또는
sudo /etc/init.d/tomcat restart
# WAS 재시작
sudo systemctl restart [your-was-service]
6단계: 연결 테스트
import java.sql.*;
public class SQLServerConnectionTest {
public static void main(String[] args) {
String url = "jdbc:sqlserver://localhost:1433;databaseName=testDB";
String user = "sa";
String password = "your_password";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(url, user, password);
System.out.println("연결 성공!");
conn.close();
} catch (Exception e) {
System.out.println("연결 실패: " + e.getMessage());
e.printStackTrace();
}
}
}
해결 방법 2 – JDBC 연결 문자열 수정
보안 정책 파일을 수정하기 어려운 환경이라면 JDBC URL에 옵션을 추가하는 방법도 있습니다.
기본 방법: SSL 비활성화
// SSL 암호화 비활성화 (내부 네트워크용)
String url = "jdbc:sqlserver://localhost:1433;databaseName=testDB;encrypt=false";
// 또는 인증서 검증 무시
String url = "jdbc:sqlserver://localhost:1433;databaseName=testDB;encrypt=true;trustServerCertificate=true";
상세 옵션 설명
// 모든 보안 옵션 명시
String url = "jdbc:sqlserver://localhost:1433;" +
"databaseName=testDB;" +
"encrypt=false;" + // SSL 암호화 비활성화
"trustServerCertificate=true;" + // 인증서 신뢰
"loginTimeout=30;" + // 연결 타임아웃
"integratedSecurity=false"; // Windows 인증 비활성화
옵션별 설명:
| 옵션 | 값 | 설명 |
|---|---|---|
| encrypt | false | SSL 암호화 사용 안 함 (내부망) |
| encrypt | true | SSL 암호화 사용 |
| trustServerCertificate | true | 서버 인증서 검증 건너뛰기 |
| trustServerCertificate | false | 서버 인증서 검증 (기본값) |
보안 권장사항:
- 내부 네트워크:
encrypt=false사용 가능 - 외부 접속:
encrypt=true;trustServerCertificate=true권장 - 프로덕션: 정식 SSL 인증서 설치 필요
해결 방법 3 – JDBC 드라이버 업그레이드
구버전 JDBC 드라이버를 최신 버전으로 업그레이드하면 문제가 해결될 수 있습니다.
Maven 설정
<!-- pom.xml -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.4.2.jre8</version>
</dependency>
Gradle 설정
// build.gradle
dependencies {
implementation 'com.microsoft.sqlserver:mssql-jdbc:12.4.2.jre8'
}
수동 다운로드
Microsoft SQL Server JDBC Driver 공식 다운로드
버전 선택 가이드:
- Java 8:
mssql-jdbc-12.4.2.jre8.jar - Java 11:
mssql-jdbc-12.4.2.jre11.jar - Java 17:
mssql-jdbc-12.4.2.jre17.jar
해결 방법 4 – SQL Server 설정 변경
SQL Server 측에서 암호화 설정을 조정하는 방법입니다.
SQL Server Configuration Manager 설정
- SQL Server Configuration Manager 실행
- SQL Server 네트워크 구성 → 프로토콜 선택
- TCP/IP 우클릭 → 속성
- 플래그 탭에서 다음 설정:
- ForceEncryption: No
- Certificate: (비워둠)
- SQL Server 서비스 재시작
T-SQL로 확인
-- 현재 암호화 설정 확인
SELECT
SERVERPROPERTY('IsIntegratedSecurityOnly') AS IntegratedSecurity,
CONNECTIONPROPERTY('net_transport') AS Protocol,
CONNECTIONPROPERTY('encrypt_option') AS EncryptOption;
실전 디버깅 방법
상세 로그 활성화
// 연결 시 상세 정보 출력
import java.sql.*;
public class DetailedConnectionTest {
public static void main(String[] args) {
String url = "jdbc:sqlserver://localhost:1433;databaseName=testDB";
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("Java Home: " + System.getProperty("java.home"));
System.out.println("Security File: " + System.getProperty("java.home") +
"/lib/security/java.security");
try {
// JDBC 드라이버 로드
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
System.out.println("드라이버 로드 성공");
// 연결 시도
Connection conn = DriverManager.getConnection(url, "sa", "password");
System.out.println("연결 성공!");
// 연결 정보 확인
DatabaseMetaData meta = conn.getMetaData();
System.out.println("Database: " + meta.getDatabaseProductName());
System.out.println("Version: " + meta.getDatabaseProductVersion());
System.out.println("Driver: " + meta.getDriverName());
System.out.println("Driver Version: " + meta.getDriverVersion());
conn.close();
} catch (Exception e) {
System.out.println("오류 발생:");
e.printStackTrace();
}
}
}
네트워크 연결 테스트
# SQL Server 포트 확인
telnet localhost 1433
# 또는
nc -zv localhost 1433
# Windows
Test-NetConnection -ComputerName localhost -Port 1433
환경별 상세 가이드
CentOS / RHEL 환경
# 1. Java 경로 확인
alternatives --display java
# 2. 보안 파일 위치
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-2.6.8.0.el7_3.x86_64/jre/lib/security/
# 3. 파일 수정
sudo vi /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/security/java.security
# 4. Tomcat 재시작
sudo systemctl restart tomcat
Ubuntu / Debian 환경
# 1. Java 경로 확인
update-alternatives --config java
# 2. 보안 파일 위치
/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/
# 3. 파일 수정
sudo nano /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.security
# 4. 서비스 재시작
sudo service tomcat8 restart
Windows 환경
# 1. Java 경로 확인
where java
echo %JAVA_HOME%
# 2. 보안 파일 위치
C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\java.security
# 3. 메모장으로 수정 (관리자 권한 필요)
notepad "C:\\Program Files\\Java\\jdk1.8.0_261\\jre\\lib\\security\\java.security"
# 4. 서비스 재시작
net stop tomcat9
net start tomcat9
추가 오류 케이스별 해결
Case 1: “비밀번호가 틀렸습니다”
-- SQL Server에서 사용자 확인
USE master;
GO
-- 로그인 확인
SELECT name, type_desc, is_disabled
FROM sys.server_principals
WHERE name = 'your_username';
-- 비밀번호 재설정
ALTER LOGIN your_username WITH PASSWORD = 'NewPassword123!';
GO
Case 2: “데이터베이스에 연결할 수 없습니다”
-- 데이터베이스 목록 확인
SELECT name FROM sys.databases;
-- 사용자 권한 확인
EXEC sp_helpuser 'your_username';
-- 권한 부여
USE your_database;
GRANT SELECT, INSERT, UPDATE, DELETE TO your_username;
Case 3: “Named Pipes Provider 오류”
// 연결 문자열에 인스턴스명 추가
String url = "jdbc:sqlserver://localhost\\\\SQLEXPRESS:1433;databaseName=testDB";
// 또는 TCP/IP 강제
String url = "jdbc:sqlserver://localhost:1433;databaseName=testDB;networkProtocol=tcp";
보안 고려사항
프로덕션 환경 권장사항
- SSL 인증서 설치
- 정식 SSL 인증서를 SQL Server에 설치
encrypt=true+ 인증서 검증 활성화
- 최소 권한 원칙
- sa 계정 사용 금지
- 애플리케이션 전용 계정 생성
- 필요한 최소 권한만 부여
- 네트워크 분리
- 데이터베이스는 내부 네트워크에만 노출
- 방화벽 규칙으로 IP 제한
개발/테스트 환경
// 개발 환경: SSL 비활성화 가능
String devUrl = "jdbc:sqlserver://localhost:1433;databaseName=testDB;encrypt=false";
// 운영 환경: SSL 필수
String prodUrl = "jdbc:sqlserver://prod-server:1433;databaseName=prodDB;encrypt=true;trustServerCertificate=false";
마무리 – 문제 해결 우선순위
1순위: JDBC URL에 encrypt=false 추가
- 가장 빠르고 간단한 해결책
- 내부 네트워크에서 안전
2순위: java.security 파일 수정
- 근본적인 해결책
- 재부팅 필요 없음
- 다른 애플리케이션에도 영향
3순위: JDBC 드라이버 업그레이드
- 장기적으로 가장 안전
- 호환성 테스트 필요
최종 권장:
- 개발 환경:
encrypt=false사용 - 운영 환경: java.security 수정 + 정식 SSL 인증서
이 가이드대로 따라하시면 99% 이상 문제가 해결됩니다. 그래도 해결이 안 된다면 댓글로 오류 메시지 전문과 환경 정보를 공유해주세요!
참고 자료: