성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>System.Data.SqlClient는 SSL 3.0/TLS 1.0만 지원하는 듯!</h1> <p> 이 질문 덕분에,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > windows 2008 r2에서 ms-sql 2008 서버사용시 tls문제점 ; <a target='tab' href='http://www.sysnet.pe.kr/3/0/1523'>http://www.sysnet.pe.kr/3/0/1523</a> </pre> <br /> TLS 통신 관련해서 좀 더 깊게 살펴보게 되는군요. 이 글에서는 클라이언트 측의 암호화 프로토콜 지정에 관해서만 다뤄보겠습니다.<br /> <br /> SQL 서버로의 DB 연결 문자열에 Encrypt 속성을 주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > string db = "TrustServerCertificate=true;<a target='tab' href='https://docs.microsoft.com/ko-kr/dotnet/api/system.data.sqlclient.sqlconnection.connectionstring'>Encrypt=true</a>;Password=testuser2008;Persist Security Info=True;User ID=testuser;Initial Catalog=TestDB;Data Source=192.168.0.23"; SqlConnection cn = new SqlConnection(db); cn.Open(); cn.Close(); </pre> <br /> 이제 SQL 서버와의 통신을 암호화하게 됩니다. 그런데 애석하게도, 연결 문자열에는 구체적인 암호화 프로토콜을 지정할 수 있는 방법이 없습니다. 대신 TDS 프로토콜이 의존하는 SCHANNEL에서는 가능합니다. (2008 R2 이상의) 윈도우 설치 시 기본 상태에서는 SCHANNEL에 SSL 2.0을 제외하고는 SSL 3.0/TLS 1.0/TLS 1.1/TLS 1.2가 활성화되어 있습니다. 또한 프로토콜 간의 우선 순위는 기본적으로 TLS 1.0, SSL 3.0 순입니다.<br /> <br /> 이 때문에 아무런 설정 없이 SqlConnection 보안 연결을 하게 되면 TLS 1.0 프로토콜로 먼저 시도하게 됩니다. 이를 알 수 있는 방법은 Network Monitor 같은 도구를 이용해 패킷을 캡쳐해야 합니다. 그런데, 만약 SQL 서버 측에서 TLS 1.0을 막아놨다면 어떻게 될까요? 이 때의 네트워크 패킷을 가로채 보면, SQL 클라이언트 측에서 TLS 1.0 버전으로 handshake를 시도하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Frame: Number = 56892, Captured Frame Length = 193, MediaType = ETHERNET + Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[00-15-5D-00-05-04],SourceAddress:[00-26-66-86-98-F8] + Ipv4: Src = 192.168.0.95, Dest = 192.168.0.23, Next Protocol = TCP, Packet ID = 27873, Total IP Length = 179 + Tcp: Flags=...AP..., SrcPort=14543, DstPort=1433, PayloadLen=139, Seq=2992396582 - 2992396721, Ack=3722507225, Win=260 (scale factor 0x8) = 66560 + Tds: Prelogin, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 0, Flags=...AP..., SrcPort=14543, DstPort=1433, PayloadLen=139, Seq=2992396582 - 2992396721, Ack=3722507225, Win=66560 TLSSSLData: Transport Layer Security (TLS) Payload Data - TLS: TLS Rec Layer-1 HandShake: Client Hello. - TlsRecordLayer: TLS Rec Layer-1 HandShake: ContentType: HandShake: - Version: TLS 1.0 Major: 3 (0x3) Minor: 1 (0x1) Length: 126 (0x7E) - SSLHandshake: SSL HandShake ClientHello(0x01) HandShakeType: ClientHello(0x01) Length: 122 (0x7A) <span style='color: blue; font-weight: bold'>+ ClientHello: TLS 1.0</span> </pre> <br /> SQL 서버 측에는 TLS 1.0 프로토콜 대신 SSL 3.0 지원을 하도록 한 경우이므로 이에 대한 응답으로 다음과 같이 SSL 3.0 통신을 명시하게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Frame: Number = 56893, Captured Frame Length = 1535, MediaType = ETHERNET + Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[00-26-66-86-98-F8],SourceAddress:[00-15-5D-00-05-04] + Ipv4: Src = 192.168.0.23, Dest = 192.168.0.95, Next Protocol = TCP, Packet ID = 1599, Total IP Length = 0 + Tcp: Flags=...AP..., SrcPort=1433, DstPort=14543, PayloadLen=1481, Seq=3722507225 - 3722508706, Ack=2992396721, Win=514 (scale factor 0x8) = 131584 + Tds: Prelogin, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 0, Flags=...AP..., SrcPort=1433, DstPort=14543, PayloadLen=1481, Seq=3722507225 - 3722508706, Ack=2992396721, Win=131584 TLSSSLData: Secure Sockets Layer (SSL) Payload Data - SSL: SSLv3 Rec Layer-1 HandShake: Server Hello. Certificate. Server Hello Done. - SslV3RecordLayer: SSLv3 Rec Layer-1 HandShake: ContentType: HandShake: <span style='color: blue; font-weight: bold'>+ Version: SSL 3.0</span> Length: 1468 (0x5BC) - SSLHandshake: SSL HandShake Server Hello Done(0x0E) HandShakeType: ServerHello(0x02) Length: 77 (0x4D) + ServerHello: 0x1 HandShakeType: Certificate(0x0B) Length: 1379 (0x563) + Cert: 0x1 HandShakeType: Server Hello Done(0x0E) Length: 0 (0x0) </pre> <br /> 이후 SQL 서버와 클라이언트는 SSL 3.0 통신을 하게 됩니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 보시는 바와 같이 SqlConnection 개체는 Open을 하면 그 하부 단에서 우선 TLS 1.0 프로토콜로 시작하게 됩니다. 그렇다면, 이 상태에서 클라이언트 측의 TLS 1.0 프로토콜을 막아버리면 어떻게 될까요? (참고로, 레지스트리 변경 후 EXE 프로세스만 재시작하면 반영됩니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 </pre> <br /> 그럼, 클라이언트는 처음부터 SSL 3.0 프로토콜을 이용해 HandShake 절차를 밟게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Frame: Number = 413, Captured Frame Length = 120, MediaType = ETHERNET + Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[00-15-5D-00-05-04],SourceAddress:[00-26-66-86-98-F8] + Ipv4: Src = 192.168.0.95, Dest = 192.168.0.23, Next Protocol = TCP, Packet ID = 4335, Total IP Length = 106 + Tcp: Flags=...AP..., SrcPort=2841, DstPort=1433, PayloadLen=66, Seq=1547634953 - 1547635019, Ack=3464005589, Win=260 (scale factor 0x8) = 66560 - Tds: Prelogin, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 0, Flags=...AP..., SrcPort=2841, DstPort=1433, PayloadLen=66, Seq=1547634953 - 1547635019, Ack=3464005589, Win=66560 - PacketHeader: SPID = 0, Size = 66, PacketID = 0, Window = 0 PacketType: Prelogin, 18(0x12) Status: End of message true, ignore event false, reset connection false Length: 66 (0x42) SPID: 0 (0x0) PacketID: 0 (0x0) Window: 0 (0x0) PreLoginPacketData: TLSSSLData: Secure Sockets Layer (SSL) Payload Data - <span style='color: blue; font-weight: bold'>SSL: SSLv3 Rec Layer-1 HandShake: Client Hello.</span> - SslV3RecordLayer: SSLv3 Rec Layer-1 HandShake: ContentType: HandShake: + Version: SSL 3.0 Length: 53 (0x35) + SSLHandshake: SSL HandShake ClientHello(0x01) </pre> <br /> 나아가서, 다음의 레지스트리 키를 등록해 SSL 3.0도 비활성화하면 어떻게 될까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client] "Enabled"=dword:00000000 "DisabledByDefault"=dword:00000001 </pre> <br /> 이후부터는 TDS:Prelogin, TDS:Response 패킷 정도만 보이고 더 이상 암호화 통신이 불가능하게 되어 이런 패킷 순서를 보이게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0x0 736 오후 2:40:30 2015-01-03 11.9265788 System TESTCLN SQLSVRR2 TCP TCP:Flags=......S., SrcPort=2347, DstPort=1433, PayloadLen=0, Seq=3846412218, Ack=0, Win=8192 ( Negotiating scale factor 0x8 ) = 8192 {TCP:10, IPv4:1} 0x0 737 오후 2:40:30 2015-01-03 11.9266810 System SQLSVRR2 TESTCLN TCP TCP:Flags=...A..S., SrcPort=1433, DstPort=2347, PayloadLen=0, Seq=1189447900, Ack=3846412219, Win=8192 ( Negotiated scale factor 0x8 ) = 2097152 {TCP:10, IPv4:1} 0x0 738 오후 2:40:30 2015-01-03 11.9316325 System TESTCLN SQLSVRR2 TCP TCP:Flags=...A...., SrcPort=2347, DstPort=1433, PayloadLen=0, Seq=3846412219, Ack=1189447901, Win=260 (scale factor 0x8) = 66560 {TCP:10, IPv4:1} 0x0 739 오후 2:40:30 2015-01-03 11.9324884 System TESTCLN SQLSVRR2 <span style='color: blue; font-weight: bold'>TDS TDS:Prelogin</span>, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 1, Flags=...AP..., SrcPort=2347, DstPort=1433, PayloadLen=88, Seq=3846412219 - 3846412307, Ack=1189447901, Win=66560 {TDS:11, TCP:10, IPv4:1} 0x0 740 오후 2:40:30 2015-01-03 11.9326110 System SQLSVRR2 TESTCLN <span style='color: blue; font-weight: bold'>TDS TDS:Response</span>, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 1, Flags=...AP..., SrcPort=1433, DstPort=2347, PayloadLen=43, Seq=1189447901 - 1189447944, Ack=3846412307, Win=131840 {TDS:11, TCP:10, IPv4:1} 0x0 741 오후 2:40:30 2015-01-03 11.9333909 System SQLSVRR2 TESTCLN TCP TCP:Flags=...A...F, SrcPort=1433, DstPort=2347, PayloadLen=0, Seq=1189447944, Ack=3846412307, Win=515 (scale factor 0x8) = 131840 {TCP:10, IPv4:1} 0x0 742 오후 2:40:30 2015-01-03 11.9385460 System TESTCLN SQLSVRR2 TCP TCP:Flags=...A...., SrcPort=2347, DstPort=1433, PayloadLen=0, Seq=3846412307, Ack=1189447945, Win=260 (scale factor 0x8) = 66560 {TCP:10, IPv4:1} 0x0 743 오후 2:40:30 2015-01-03 11.9393830 System TESTCLN SQLSVRR2 TCP TCP:Flags=...A...F, SrcPort=2347, DstPort=1433, PayloadLen=0, Seq=3846412307, Ack=1189447945, Win=260 (scale factor 0x8) = 66560 {TCP:10, IPv4:1} 0x0 744 오후 2:40:30 2015-01-03 11.9394074 System SQLSVRR2 TESTCLN TCP TCP:Flags=...A...., SrcPort=1433, DstPort=2347, PayloadLen=0, Seq=1189447945, Ack=3846412308, Win=515 (scale factor 0x8) = 131840 {TCP:10, IPv4:1} </pre> <br /> 그와 함께, SqlConnection.Open 호출 단계에서 다음과 같은 예외 메시지가 떨어집니다.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> The instance of SQL Server you attempted to connect to requires encryption but this machine does not support it. <br /> Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. <br /> <br /> Exception Details: System.Data.SqlClient.SqlException: The instance of SQL Server you attempted to connect to requires encryption but this machine does not support it.<br /> </div><br /> <br /> 즉, SQL 서버 측에서 다른 보안 프로토콜을 지원한다고 해도 클라이언트 측에서 이미 SSL 3.0, TLS 1.0만 지원하므로 더 이상 통신이 안되는 것입니다.<br /> <br /> 혹시, 클라이언트 측에서 SSL 3.0/TLS 1.0 이외의 프로토콜로 접속하는 방법을 아시는 분은 덧글 부탁드립니다. ^^<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1116
(왼쪽의 숫자를 입력해야 합니다.)