TLS Socket 시작하기

주말 오후 1시·2023년 10월 23일
0

Socket이란?

일반적으로 소켓통신이라고 한다면 많은 사람들은 "웹 소켓"을 생각한다.
하지만 소켓통신에는 두가지의 종류가 존재한다.

  1. TCP/IP or UDP Socket
  2. WEB Socket

얼핏보면 동일해보이는 두 소켓은 작동되는 레이어로 분리됩니다.

TCP/IP or UDP 소켓은 OSI 7layer중 전송계층(Transport)에서 동작을 하며,
WEB 소켓은 어플리케이션 계층(Application)에서 동작한다.

여기에서는 네트워크 소켓인 TCP/IP or UDP 소켓을 집중적으로 서술하려 한다.

TCP VS UDP

TCP 와 UCP는 전송계층에서 데이터를 전송하는 방식의 차이입니다.
이 두가지 방식은 소켓으로 데이터를 보낼 때 선택적으로 사용이 가능합니다.

TCP의 특징

  • 연결 지향 방식으로 패킷 교환 방식(가상 회선 방식이 아님)
  • 3-way handshaking과정을 통해 연결을 설정, 4-way handshaking을 통해 해제
  • 흐름 제어 및 혼잡 제어
  • 높은 신뢰성 보장
  • UDP보다 속도가 느림
  • 전이중(Full-Duplex), 점대점(Point to Point) 방식

즉, 데이터의 손실과 신뢰성이 중요하다면 TCP 방식을 사용해야 합니다.

UDP의 특징

  • 비연결형 서비스로 데이터그램 방식을 제공
  • 정보를 주고 받을 때 정보를 보내거나 받는다는 신호절차를 거치지 않음
  • UDP헤더의 CheckSum 필드를 통해 최소한의 오류만 검출
  • 신뢰성이 낮음
  • TCP보다 속도가 빠름

즉, 데이터의 손실과 신뢰성보다 속도가 중요하다면 UDP를 사용해야한다.

Socket

TCP/IP 방식으로 소켓을 만들때 소켓에는 두가지 역할이 있습니다.

  1. Server (받는 주체)
  2. Client (주는 주체)

TCP Socket Server

//TCP 소켓을 만들기 위해 net 라이브러리 import
import net from 'net';

const serverOptions = {
	port: 3000
    //host를 따로 지정하지 않으면 localhost(127.0.0.1)을 의미한다.
}

const server = net.createServer((socket) => {

	// 받는 데이터 인코딩
    //utf8로 인코딩 하지 않으면 Buffer type으로 들어온다.
	socket.setEncoding('utf8');

	// Server로 data가 들어올 경우ㅡ
	socket.on('data', function (data) {
		console.log(data);
        //연결된 socket으로 데이터 전달
        socket.write(data)
	});
    
    // Server에서 error 이벤트 발생시ㅡ
	socket.on('error', function (data) {
		console.log(data);
	});
    
    

});

// listening
server.listen(serverOptions, () => {
	//서버 생성시 에러
    server.on('error', function (err) {
        console.log('err: ', err);
    });
});

TCP Socket Client

//TCP 소켓을 만들기 위해 net 라이브러리 import
import net from 'net';

const serverOptions = {
	port: 3000
    //host를 따로 지정하지 않으면 localhost(127.0.0.1)을 의미한다.
}

const client = net.connect(serverOptions);

// listening
server.listen(serverOptions, () => {
	//서버 생성시 에러
    server.on('error', function (err) {
        console.log('err: ', err);
    });
});

위와 같이 구현하게 되면 데이터를 주고받을 때 큰 문제점이 생긴다.
바로 평문으로 전달되는 데이터이다.

"해당 포트가 외부에 노출된다면?"
해커가 민감한 데이터를 바로 볼 수 있네?

라는 생각으로 이어질 수 있습니다. 때문에 Socket으로 주고받는 데이터를 보호하기 위해

보안 프로토콜인 TLS 방식을 사용 합니다.

TLS

TLS란?

TLS는 Transport Layer Security(전송 계층 보안)의 약자입니다.

보안이라는 목적이 들어간 만큼 TLS에서는 평문으로 주고 받는 데이터를 암호화하여 전달합니다.
** SSL 3.0은 TLS 1.0과 동일

암호화 방식에는 두가지가 존재합니다.

대칭키 암호화

암호화 복호화 키가 동일

비대칭키 암호화

암호화 복호화 키가 다름

이때, 비대칭키 암호화 방식은 키 한쌍으로 이루어져 있습니다.

외부에 공개되어 상대방에게 전달하여 암호화를 요청할때 사용하는 공개키 (Public Key)
공개키로 암호화된 내용을 복호화하기 위해 외부에 공개되지 않는 개인키(Private Key)

TLS Socket Server

//net 라이브러리가 아닌 tls 라이브러리 받아온다.
import tls from "node:tls"

const serverSecurOptions = {
	//데이터 암복호화를 위한 인증서
    key:"",
    cert:"",
    ca:""
}

const serverOptions = {
	port: 3000
}

const server = tls.createServer(serverSecurOptions, (socket) => {

	// 받는 데이터 인코딩
    //utf8로 인코딩 하지 않으면 Buffer type으로 들어온다.
	socket.setEncoding('utf8');

	// Server로 data가 들어올 경우ㅡ
	socket.on('data', function (data) {
		console.log(data);
        //연결된 socket으로 데이터 전달
        socket.write(data)
	});
    
    // Server에서 error 이벤트 발생시ㅡ
	socket.on('error', function (data) {
		console.log(data);
	});

});

// listening
server.listen(serverOptions, () => {
	//서버 생성시 에러
    server.on('error', function (err) {
        console.log('err: ', err);
    });
});

TLS Socket Client

//TLS 소켓  Client를 만들기 위해 TLS 라이브러리 import
import tls from "node:tls"

const serverOptions = {
	port: 3000
    //데이터 암복호화를 위한 인증서
    key:"",
    cert:"",
    ca:""
}

const client = tls.connect(serverOptions);

// listening
server.listen(serverOptions, () => {
	//서버 생성시 에러
    server.on('error', function (err) {
        console.log('err: ', err);
    });
});

출처

Node net api 공식 문서
Node tls api 공식 문서

profile
일주일을 모아보자

0개의 댓글