소프트웨어를 개발하다 보면, 공유되어야 할 자원이 존재할 수 있습니다.

공유자원은 서로 다른 두 태스크가 각자 처리를 마친 후, 결과가 하나로 취합되어야 하는 경우에 필요합니다.

하나로 취합하는 경우, 상호 배제 개념이 중요합니다.


싱글 테스크 와 멀티 테스크

싱글 태스크(싱글 프로세스 + 싱글 스레드) 프로그램이면 문제가 되질 않습니다. 두 태스크는 순차적으로 처리되므로, 공유자원의 동시성 문제가 존재하지 않기 때문입니다.

반면에 멀티 태스크(멀티 프로세스 또는 멀티 스레드) 프로그램이면 문제가 발생할 수 있습니다. 두 태스크가 동시적으로 처리되면서 공유자원이 예기치 못한 결과로 취합될 수 있기 때문입니다.

다음은 은행 입-출금 기능이 싱글 태스크, 멀티 태스크로 구현된 예시입니다.

싱글 테스크

보유 금액: 50,000 (공유 자원)

입금 태스크

  • 현재 보유된 금액을 조회. (50,000)
  • 입금할 금액을 확인 (10,000)
  • 입금 처리. (50,000 + 10,000)

출금 태스크

  • 현재 보유된 금액을 조회. (60,000)
  • 출금할 금액을 확인 (20,000)
  • 출금 처리. (60,000 - 20,000)

최종 보유금액은 40,000(40,000) 이 됩니다.

멀티 테스크

보유 금액: 50,000 (공유 자원)

입금 테스크

  • 현재 보유된 금액을 조회 (50,000)

  • 입금할 금액을 확인 (10,000)

  • 입금 처리. (50,000 + 10,000)

최종 보유금액은 60,000(40,000) 이 됩니다.

출금 테스크

  • 현재 보유된 금액을 조회 (50,000)

  • 출금할 금액을 확인 (20,000)
  • 출금 처리. (50,000 - 20,000)

임계영역

위 예시에서 살펴봤다시피,

멀티 태스크 프로그램을 개발하면, 공유자원을 사용하는 부분을 순차적으로 처리하도록 보장해야 합니다. 이때, 순차적으로 처리해야 하는 부분을 임계영역 이라 일컫습니다.

임계영역 이 순차적으로 처리될 수 있게 하는 방법은 크게 2가지가 있습니다.

  • 뮤텍스(Mutex)
  • 세마포어(Semaphore)


뮤텍스

자원의 선점을 통해, 순차 처리를 수행하는 방법입니다.

이때, 선점될 자원은 하나의 객체로 처리 되며 이를 Lock 또는 Key 라고 부릅니다.

하나의 태스크가 임계 영역을 진입할 때, Lock을 획득하고 진입 하는 방식입니다. 이렇게 되면 다른 태스크들은 Lock을 획득 할 수 있을때 까지 줄지어서 기다리게 됩니다.

Lock을 획득한 태스크가 임계 영역을 처리하고 나면 Lock을 반납하게 됩니다. 그 후, 대기하던 태스크들 중 하나가 Lock을 획득하여 임계 영역을 수행하게 됩니다.

뮤텍스는 단일 공유 자원 처리에 적합

만약 각 태스크가 공유 자원이 2개 이상 필요한 경우는 어떨까요?

각 자원에 대한 Lock 을 생성하고 태스크에 두개의 Lock 에 대한 처리가 필요하게 됩니다.

이는 공유 자원 추가로 인해 변경 사항이 모든 테스크에 반영되어야 하므로, 유지보수를 어렵게 만드는 요인이 됩니다.

또한 공유 자원 개수가 많아 지면 분기 처리도 복잡하고 어려워 지는 문제도 발생합니다.


세마포어

뮤텍스의 다중 공유 자원 처리에 대한 단점을 보완한 방법입니다.

세마포어는 하나의 자원에 대한 락킹 개념보다 조금더 나아가, 자원 사용 카운팅 기법으로 순차 처리를 보장하는 방법입니다.

테스크가 임계 영역을 진입할 때, 진입 가능한 숫자를 참고합니다.

자원 사용 카운팅이 0보다 크다면, 테스크가 임계 영역을 집입하고 자원 사용 카운팅을 하나 감소시킵니다.

만약, 자원 사용 카운팅이 0이라면 테스크는 추가 카운팅이 생길 때 까지 대기하게 됩니다.


데드락

앞서 살펴본 2가지 방법은 널리 사용되고 있는 기본적인 개념입니다.

하지만, 공유 자원을 2개 이상 사용하는 임계 영역을 처리하는 경우 교착 상태가 발생할 수 있습니다.

공유 자원 A, B 가 있다고 가정할 때, 다음의 뮤텍스 방법은 교착 상태 즉, 데드락이 발생할 수 있습니다.

TASK-1

  • Locking(A)
  • Locking(B)

TASK-2

  • Locking(B)
  • Locking(A)

위 예시는 TASK-1공유 자원 B의 락이 해제 되길 기다리고 있으며, 반대로 TASK-2공유 자원A가 해제 되길 기다리고 있습니다. 이는 결국 무한정 대기하게 되는 데드락이 발생하게 됩니다.

세마포어 기법도 마찬가지로 적용됩니다.

데드락 해결 방법

해결 방법은 여러 가지가 존재하며, 상황에 맞게 처리하는것이 중요합니다.

  • 타임아웃 설정

    자원의 대기 타임아웃을 설정하여 교착 상태에 빠진 테스크중 하나를 타임아웃으로 포기하게 하는 방법 입니다.

  • 진입 순서 일치

    공유자원의 임계영역 진입 처리 순서를 동일하게 하여 자원 요청 방향이 원형을 이루지 않도록 처리하는 방법입니다.


정리

  • 뮤텍스는 하나의 락 객체를 통해 임계 영역이 하나의 태스크만 처리할 수 있도록 고안된 방법입니다.
  • 세마포어는 공유자원 접근 가능 카운트를 정의해, 정의한 수 만큼 태스크가 처리할 수 있도록 고안된 방법입니다.
  • 공유 자원을 2개 이상 사용하는 임계영역은 데드락이 발생 할 수 있으므로, 유념해야 합니다.
  • 세마포어의 카운팅을 1로 하면 뮤텍스와 같은 효과를 누릴 수 있습니다.

'운영체제' 카테고리의 다른 글

[운영체제] 스레드  (0) 2021.07.22
[운영체제] 프로세스  (0) 2021.07.21

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

안녕하세요.

오늘은 스레드에 대해 포스팅 합니다.

프로세스 포스팅을 읽고 오시면 좀 더 쉽게 읽으실 수 있습니다.


CPU 스레드

CPU 하드웨어를 평가할 때 참고하는 많은 정보들이 있습니다.

대표적으로는 아래의 두정보가 있습니다.

  • 코어 수
  • 스레드 수

코어 수는 컴퓨터 데이터인 이진수를 계산 할 수 있는 계산기의 갯수 입니다. 이는 하드웨어적인 개념 입니다.

스레드 수는 이진수를 계산 할 수 있는 능력입니다. 이는 소프트웨어적인 개념 입니다.

보통은 코어 수가 곧 스레드 수 입니다. 하지만 인텔이 개발한 하이퍼스레딩 같은 기술을 접목하면 각 코어당 2개의 스레드를 사용 할 수 있습니다.

정리하자면 코어 수의 두배인 스레드 를 사용할 수 가 있습니다.

하지만 이해가 잘 안갑니다. 계산기는 하나 인데 어떻게 2배의 처리 능력을 가질 수 있는것일까요?

아래의 프로세스 2개가 존재한다고 가정해봅시다.

프로세스

이름걸리는 시간데이터
A10초1111111111
B4초0000

1코어 1스레드는 두 프로세스를 마치는 시간은 14초 입니다.

A 프로세스가 선 처리되던 (11111111110000)

B 프로세스가 선 처리되던 (00001111111111) 간에 총 처리 시간은 같습니다.

하지만 B 프로세스의 처리 결과를 기다리는 사용자가 느끼는 경험은 많이 다릅니다.

첫번째 경우는 B 프로세스가 처리 될 때까지 걸린시간은 14초 입니다.

반면에 두번째 경우는 4초가 걸렸습니다.

이렇게, 처리시간이 긴 프로세스가 존재하면 상대적으로 다른 프로세스들이 늦게 끝나게 되는 경우가 발생하게 되고 이는 사용자가 여러가지 프로그램을 동시적으로 처리하는데 어려움을 느낄 수 있다는 것입니다.

반면에 1코어 2스레드는 어떻게 처리할까요? 아래와 같이 처리합니다.

10101010111111

CPU 입장에서 총 처리시간은 1스레드와 같은 14초입니다.

하지만 B프로세스는 8초가 걸리게 됩니다. 최악의 경우인 14초 보다 거의 2배 가량 감소하게 되었습니다.

더군다나 이렇게 나누어 처리하게 된다면 여러가지 프로그램이 동시적으로 조금씩 처리되고 사용자 입장에서는 여러 프로그램이 버벅임 없이 처리되는것을 경험하게 됩니다.

정리하자면, 스레드는 데이터를 병렬로 처리하는 능력을 의미합니다.

이 때, 착각하면 안되는 것은 CPU 입장에서는 총 처리 시간은 변함없다는 점 입니다.

CPU 하드웨어 입장에서 총 처리 시간을 줄이는 방법은 코어 갯수를 늘리는 방법 뿐입니다.


프로세스 스레드

CPU 스레드는 일을 처리할 수 있는 능력이라 소개했습니다. 운영체제는 프로세스CPU 스레드에게 할당하는 작업을 합니다.

CPU가 2개의 스레드를 제공한다고 가정 할 때, 프로세스를 2개만 처리하는 것으로 착각 할 수 있습니다. 이는 잘못된 개념이며 쉽게 설명하자면, 2개의 계산기가 있고 여러 사람(=프로세스)이 돌려 사용하는것을 의미합니다.

위에서 소개한 예시처럼 컴퓨터는CPU 스케줄링 을 통해 여러 프로세스들을 N개의 CPU 스레드 에 일을 돌아가면서 할당 합니다.

이때, 운영체제가 정의하는 스레드 의 개념은 프로세스 내부의 작업 단위로 사용됩니다.

특정 프로세스CPU에게 선택받는다고 해서, CPU는 무조건적으로 일을 진행하지 않습니다. 예를 들어, 해당 프로세스가 IO 인터럽트가 걸려있으면 CPU는 해당 프로세스 를 처리하지 않고 대기 큐에 보내 버리지요.

프로세스 입장에서는 억울 할 수 있습니다. IO 인터럽트 처리 다음에도 해야할 일이 많을 수도 있을테니깐요. 이 때, 다중 스레드를 이용하면 해당 이슈를 개선할 수 있습니다.

A 스레드는 IO 인터럽트를 처리하게 하고, B 스레드CPU가 진행 할 수 있는 일을 처리하게 했다고 가정해봅시다.

CPU는 해당 프로세스를 선택했을 때, 스레드 단위로 살펴보게 되고 처리할 수 있는 스레드가 있다면 해당 작업을 진행하게 됩니다.

정리하자면, 다중 스레드로 프로그래밍을 진행하게 된다면 CPU에게 일을 처리 받을 확률이 높아짐을 의미합니다.


프로세스 스레드 특징

프로세스 는 CODE, DATA, STACK, HEAP 영역을 가지게 됩니다.

STACK은 명령어가 수행되기 위한 작업 공간입니다.

스레드의 개별 STACK

프로세스 내부에 스레드를 만들게 되면 각 스레드는 개별 STACK 영역을 가지게 됩니다.

즉, 스레드가 3개인 프로세스는 3개의 STACK 공간을 가지게 되는것이지요.

이러한 개별 스택 공간을 통해 CPU는 독립적인 단위로 처리하는것이 가능해집니다.

스레드간 통신

프로세스의 CODE, DATA, HEAP 영역은 스레드 끼리 공유하게 됩니다.

그로인해, 스레드간 데이터 통신은 프로세스간 데이터 통신보다 쉽게 처리할 수 있는 특징이 있습니다.

자바와 같은 프로그래밍 언어를 이용해 코딩해보면 서로 다른 스레드를 처리 할 때, 특정 변수등을 같이 사용할 수 있습니다.
프로세스간 데이터 통신은 파일 통신(소켓 통신)이 베이스가 되어야 합니다.

하지만, 데이터를 공유한다는 것은 그만큼 동기화 문제가 발생할 확률로 높습니다.


멀티 프로세스 방식과 멀티 스레드 방식

프로그램을 만들 때, CPU에게 최대한 많은 일 처리를 받기 위해 사용하는 방식은 크게 두가지 입니다.

  • 멀티 프로세스 프로그래밍
  • 멀티 스레드 프로그래밍

멀티 프로세스 방식은 루트 프로세스가 존재하고, 일처리를 다수의 자식 프로세스에게 나누어 처리하여 취합하는 방식입니다.

장점은 독립성을 보장받을 수 있다는 점 입니다.

하나의 프로세스가 문제가 생기더라도 다른 프로세스에게 영향을 주지 않습니다.

단점은 데이터 통신에 많은 자원을 소비한다는 점입니다. 컨텍스트 스위칭에 따른 성능 저하가 대표적입니다.

멀티 스레드 방식은 하나의 프로세스 에 다수의 스레드(스택)에게 나누어 처리한 후 취합하는 방식입니다.

장점은 데이터 통신이 상대적으로 쉽고, 빠르고, 비용이 적습니다.

단점은 데이터를 공유하기 쉬우므로, 동기화 문제가 빈번하게 발생 할 수 있고 특정 스레드가 문제가 생기면 전체 프로세스에 영향을 줄 수 있습니다.


오늘 포스팅은 여기까지 입니다.

읽어주셔서 감사합니다.

'운영체제' 카테고리의 다른 글

[운영체제] 뮤텍스와 세마포어  (0) 2021.07.25
[운영체제] 프로세스  (0) 2021.07.21

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

안녕하세요.

오늘은 프로세스에 대해 포스팅합니다.

프로그램과 프로세스

 

컴퓨터에서 프로그램 이란 단어는 매우 많이 사용되고 있습니다.

반면에 프로세스 라는 용어는 생각보다 생소합니다. 운영체제에서는 두가지 단어의 개념을 구분해서 사용할 줄 알아야 합니다.

프로그램

하드디스크에 저장되어 있는 일련의 데이터 덩어리를 파일 이라고 일컫습니다. CPU가 해석하고 수행할 수 있는 명령어 데이터로 구성된 파일프로그램 이라고 합니다. 이미지 파일과 같은 순수 데이터는 프로그램이라 할 수 없습니다. 

프로세스

하드디스크에 저장되어 있는 프로그램 을 CPU가 수행하기 위해서는 하드디스크에 위치한 데이터를 메모리로 옮기는 작업이 필요합니다. 메모리에 옮겨진 일련의 데이터 덩어리를 프로세스 라고 일컫습니다.

 

정리하자면 프로세스프로그램 이 메모리에 옮겨진 데이터 덩어리를 의미합니다.

그러므로 프로세스실행 중인 프로그램 이라고도 불립니다.

 


프로세스 구조

 

사실 프로세스프로그램 데이터 그대로 메모리에 복사되는건 아닙니다.

OS가 프로그램 을 분석하여, 아래와 같은 프로세스 구조를 만듭니다.

 

CODE

하드디스크에서 읽어온 프로그램 데이터가 저장되는 영역입니다.

CPU가 명령어를 수행하기 위해 사용됩니다.

 

DATA

프로세스 가 수행되면서 필요한 데이터들이 저장되는 영역입니다.

OS가 프로그램 을 분석하면서 사전에 정의할 수 있는 데이터만 저장됩니다.

프로세스 가 수행(함수와 같은)되면서 생성되는 데이터들은 사전에 저장하지 못합니다.

 

STACK

프로세스 의 명령어가 수행될 때 필요한 공간으로 사용됩니다.

함수의 콜스택 지역변수 데이터들이 적재됩니다.

 

HEAP

STACK 은 공간을 사용한 후 데이터가 소멸 됩니다.

반면에 HEAP 공간은 데이터가 소멸되지 않습니다. 소멸시키기 위해서는 추가적인 소멸 명령어가 필요합니다.

CODE, DATA와 다르게 필요한 공간을 미리 계산할 수 없는 STACKHEAP은 임의의 크기가 정해진 공간을 같이 사용합니다. 따라서, STACK 또는 HEAP 메모리 사용량이 매우 많아지면 여유 공간이 없어 문제가 발생할 수 있습니다. STACK 공간을 과도하게 사용할 때는 StackOverflow, HEAP 공간을 과도하게 사용할 때는 OutOfMemery(OOM) 과 같은 에러가 발생할 수 있습니다.

 


프로그램 제어 블록(PCB)

 

컴퓨터는 하나의 프로세스만 수행하지 않고 여러 프로세스를 수행합니다.

그렇기에 메모리에는 많은 프로세스 들이 위치해 있습니다.

CPU는 어떻게 무수히 많은 프로세스 중에 특정 프로세스를 찾아내는 걸까요?

또 필요한 정보들을 취득하거나 저장하는 건 어떻게 하는 걸까요?

 

우리가 책을 읽을 때, 원하는 컨텐츠를 빠르게 찾기 위해서는 목차를 사용합니다.

CPU도 마찬가지로 프로세스 목차를 사용합니다.

이에 OSPCB 단위로 프로세스 목차를 구성하여 CPU에게 제공합니다.

 

PCBCPU프로세스를 수행하기 위해 필요한 데이터로 구성되어 있습니다.

 

PID(Process IDentification)

OS는 각 프로세스를 식별하기 위해 번호를 부여합니다. 이 식별 번호가 바로 PID 입니다.

 

포인터

CPU와 같은 공간에서 프로세스를 효율적으로 찾을 수 있도록 도와주는 정보입니다.

 

프로세스 상태

OS는 무수히 많은 프로세스를 정해진 절차대로 처리합니다. 해당 정보는 그 절차를 판단하기 위해 사용됩니다.

프로세스 상태에 따라 정해진 절차대로 수행하는 것을 프로세스 스케줄링 이라 부르며 프로세스 스케줄러 라는 프로그램이 수행합니다.

아래에서 자세히 다룰 예정입니다.

 

프로그램 카운터

해당 프로세스에서 CPU가 다음으로 실행할 명령어 위치를 가리키는 값입니다.

 

레지스터 정보

레지스터 는 쉽게 말해, 데이터를 저장할 수 있는 임시 공간입니다.

CPU프로세스를 처리하면서 필요한 데이터를 저장하고 읽는 용도로 사용합니다.

 


프로세스 스케줄링

 

현대 OS시분할 시스템을 제공합니다.

채팅을 하면서 동시에 음악을 들을 수 있는 이유는 CPU가 빠른 속도로 번갈아가면서 프로세스를 수행하기 때문입니다.

특정 프로세스CPU로 처리되기 위한 과정은 아래와 같습니다.

 

 

프로세스의 상태는 크게 5가지가 존재합니다.

생성 상태

프로그램을 메모리로 가져와 프로세스 제어 블록(PCB) 생성이 완료된 상태입니다.

 

준비 상태

실행을 기다리는 모든 프로세스가 자기 차례를 기다리고 있는 상태입니다.

실행될 프로세스CPU 스케줄러가 선택합니다.

 

실행 상태

선택된 프로세스가 타임 슬라이스를 얻어 CPU를 사용하는 상태입니다.

기존 수행되던 PCB준비 상태 또는 대기 상태로 넘어가면서 문맥 교환 오버헤드가 발생합니다.

 

대기 상태

실행 상태에 있는 프로세스가 입출력과 같은 인터럽트가 발생되면 완료될때까지 기다리는 상태입니다.

CPU가 키보드와 마우스 같은 입출력 장치의 처리를 기다리면서 생기는 병목현상을 방지합니다.

입출력 처리가 완료되면 해당 PCB준비 상태로 보냅니다.

 


문맥 교환(Context Switching)

 

CPU는 여러 프로세스를 특정 시간마다 번갈아 가면서 수행합니다.

요리 중 다른 요리를 하게 되면 기존 재료들을 냉장고에 넣고 새 재료를 배치하는 것처럼 CPU프로세스 교체 수행을 위한 준비가 필요합니다..

프로세스 를 교체할 때 CPU는 아래와 같은 과정이 필요합니다. (A 프로세스에서 B 프로세스로 교체된다고 가정합니다.)

  • A 프로세스의 정보를 A PCB 에 저장한다.
  • B 프로세스의 정보를 B PCB 로부터 가져온다.

 

이러한 준비시간을 CPU가 일을 하지 못하는 낭비시간이라 생각하여 오버헤드라 부릅니다.

문맥 교환 오버헤드를 개선하고자, 프로세스 교체 타임 슬라이스를 너무 길게 잡아도 프로세스 동시성 처리가 나빠질 수 있기 때문에 적당한 수준의 타임 슬라이스를 잡는 것이 중요합니다.

 


 

오늘 준비한 내용은 여기까지입니다.

읽어주셔서 감사합니다.

 

 

'운영체제' 카테고리의 다른 글

[운영체제] 뮤텍스와 세마포어  (0) 2021.07.25
[운영체제] 스레드  (0) 2021.07.22

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

안녕하세요.

오늘은 HTTPS 통신 에 대해 포스팅 합니다.

HTTPS 통신 은 데이터를 암호화 하여 통신하도록 설계되어 보안적인 요소가 강화된 HTTP 통신 입니다.

HTTPS 통신HTTP 통신 과 다르게 서버가 제공하는 SSL 인증서 라는 요소가 추가되었으며, 이를 통해 클라이언트는 필요한 서버의 정보를 취득하고 신뢰성을 판단합니다.

데이터 암호화

HTTPS 통신 방법에 앞서, 간단하게 데이터 암호화 개념을 살펴보면 좋습니다.

암호화 란 평문을 암호문으로 변경하는것을 의미합니다.

반대로 복호화 는 암호문을 평문으로 변경하는것을 의미합니다.

평문: 사람이 이해할 수 있는 데이터

암호화는 어떤 특정 데이터를 사용하여 수행하는데, 이 특정 데이터를 암호키 라고 부릅니다.

암호화는 크게 두가지 방식이 있습니다.

  • 대칭키 방식
  • 공개키 방식

대칭키 방식

대칭키 방식은 말그대로 암호키 가 대칭임을 의미 합니다.

암호화 할때도, 복호화 할때도 똑같은 1개의 암호키 를 사용하는 것이 특징입니다.

통신 하려는 대상 서로가 암호키 를 알고 있으면 매우 유용합니다.

하지만 불특정 다수와 통신을 하기 위한 안전한 암호키 전달이 무척 어렵습니다.

해커가 중간에 암호키 를 취득 해버리면 데이터를 암호화 하는게 의미가 없기 때문입니다.

Q. 암호키암호화 해서주면 안되나요? A. 암호화 를 하기위해서는 무조건 최초로 평문으로된 암호키 를 넘겨주어야만 합니다. 암호키암호화 해버리면 클라이언트는 복호화 를 할 수 있는 키를 모르기 때문입니다.

공개키 방식

공개키 방식은 암호키 가 두가지 존재합니다.

  • 공개키
  • 비공개키(개인키, 비밀키)

대칭키 방식 과는 다르게 암호화 할때 공개키를 사용했으면 복호화비밀키 를 사용해야 합니다.

반대로, 암호화 할때 비밀키 를 사용했다면 복호화공개키 로만 가능합니다.

공개키 방식의 장점

공개키 방식대칭키 방식 의 키를 안전하게 전달하기 어려운 단점을 어느정도 해소 하였습니다.

서버가 개인키 를 소유하고 있고, 불특정 다수에게 공개키 를 전달합니다.

이때, 해커가 공개키 를 획득 할 수 있고 그로인해 서버가 내려주는 데이터 를 해석은 할 수 있지만 클라이언트에게 공격하지는 못합니다.

예를들어, 서버가 클라이언트에게 A의 장소 를 알려줬습니다. 이때 해커는 공개키 를 취득해 복호화 하여 내용을 읽었고 클라이언트에게 B의 장소 로 속이고 싶습니다.

해커가 데이터를 변경하더라도 서버가 가지고 있는 비밀키 를 알아야 클라이언트가 속을 수 있는 암호문 을 만들 수 있습니다.

해커가 임의로 암호문을 만들어버리면 클라이언트는 공개키 로 복호화에 실패할것이고, 결국 클라이언트에게 공격하지 못하는 상황이 발생합니다.

물론 클라이언트가 서버의 서비스를 이용 못하는건 있습니다. 하지만 공격 받지 않는것이 핵심입니다.

반대로 클라이언트가 서버로 데이터를 보낼 때는 공개키 로 데이터를 암호화 하여 보냅니다.

해커는 공개키 만알고 있기 때문에 클라이언트 데이터를 읽지 못합니다. 왜냐면 공개키 방식공개키암호화 를 하면 비밀키 로만 복호화 를 진행할 수 있기 때문입니다.

정리하자면 공개키 방식 은 클라이언트로 하여금 데이터가 변경되지 않음을 보장할 수 있고 안전하게 데이터를 서버로 보낼 수 있는 장점이 있습니다.

공개키 방식의 단점

하지만 공개키 방식도 한계가 존재합니다. 클라이언트 → 서버로 데이터를 암호화 해서 보내는건 문제가 되지 않습니다. 해커가 읽지도 못하니깐요.

하지만 서버 → 클라이언트로 보내는 데이터는 해커가 읽을 수 있습니다. 만약 데이터가 민감한 개인 정보같은게 포함되어 있다면 해커가 읽는것만으로도 피해가 생길 수 있기 때문입니다.

또한 공개키 방식대칭키 방식 보다 암-복호화 속도가 느립니다.

SSL 인증서

HTTPS 통신 에서는 서버가 SSL 인증서 를 제공한다고 언급했습니다.

SSL 인증서는 크게 두가지 역할을 수행합니다.

  • 서버 본인이 신뢰할 수 있는 서버임을 증명하는 수단.
  • 서버가 제공하는 공개키를 전달.

SSL 인증서 는 서버의 신뢰성을 판단할 수 있는 수단이라 했는데, 다짜고짜 클라이언트에게 SSL 인증서 를 내밀면 신뢰할 수 있을까요?

예를들어, 모르는 사람이 다가와서 나 믿을 수 있는 사람이야 라고 말하면 여러분을 믿을 수 있으신가요?

그렇기에 SSL 인증서 의 신뢰성을 대신 보장하는 제 3자가 존재합니다.

그 3자를 CA(Certificate authority) 혹은 Root Certificate 라 일컫는 기업들입니다.

해당 기업들은 세계적인 기업으로써, 신뢰성이 엄격하게 공인된 기업들만 CA로써, 참여할 수 있습니다.

이러한 기업은 SSL 인증서 를 신청한 기업들이 신뢰성있는 기업인지 평가한 후 발급을 진행합니다.

CA 기업들은 잘 알려진 기업들로써, HTTPS 통신을 지원하는 클라이언트(대표적으로 브라우저)들은 CA 리스트 를 보유하고 있습니다. 그렇기에, 클라이언트는 SSL 인증서 를 받은 후 정보를 읽어 CA 리스트 대조를 통해, CA 가 발급한 SSL 인증서 의 유무를 판단하고 신뢰성을 평가합니다.

CA 가 발급하지 않은 SSL 인증서 는 클라이언트가 신뢰성을 낮게 평가합니다.

SSL 인증서 암호화

SSL 인증서는 비공개키 방식 으로 암호화하여 클라이언트에게 전달됩니다.

이때, 암호화 를 수행하는 대상은 서버가 아닌, CA 에서 자체적으로 소요한 비밀키 를 통해 암호화 를 진행합니다.

SSL 인증서 를 서버에서도 변조하여 클라이언트에게 공격할 수 없습니다. 비밀키 를 모르기 때문입니다.

CA공개키는 이미 널리 알려진 정보로써, 클라이언트가 CA 리스트 와 함께 공개키 도 보유하고 있습니다. 그렇기에 위에 앞서 언급한 공개키 방식 장점을 잘 활용하고 있다고 볼 수 있습니다. SSL 인증서 가 위조되지 않음을 보장받을 수 있기 때문입니다.

SSL 인증서에 포함된 공개키

SSL 인증서엔 공개키가 포함되어 있는데 이는, CA공개키가 아닙니다. 서버가 클라이언트와 보안 통신을 하기위해 서버가 직접 생성한 공개키 입니다.

서버가 CA 에게 SSL 인증서 의 발급 신청을 할 때, 몇몇 서버 데이터를 전달하는데 필수적으로 공개키 도 전달이 되어야 합니다.

뒤에 설명할 SSL 통신 에서는 클라이언트가 SSL 인증서 를 통해 서버의 공개키 를 취득하고, 비공개 방식 으로 보안 통신하는 절차가 있기 때문에 필수적으로 필요합니다.

SSL 통신

공개키 방식 으로 통신을 하면, 서버 → 클라이언트로 데이터를 내려줄땐 조금 문제가 될 순 있지만, 어느정도 감안하고 보안 통신 방법으로 사용할 수 있을거 같습니다.

하지만, 큰 단점이 있는데요.

그것은 바로 공개키 방식은 암호화 복호화 하는 과정이 느리다 라는 것 입니다.

웹통신이 느리면, 문제가 될 수 있기 때문에 SSL 통신 은 상대적으로 빠른 대칭키 방식 으로 메인 통신을 진행합니다.

하지만, 대칭키는 공격자가 알면 너무나도 쉽게 데이터를 변조하여 대상을 속일 수 있기 때문에 매우 위험합니다. SSL 통신은 어떻게 이런 이슈들을 해결했을까요?

SSL 통신 방법

결론적으로 말하자면, SSL 통신은 공개키 방식대칭키 방식 둘 다 사용합니다.

SSL 통신은 다음의 아이디어를 사용합니다.

공개키 방식 으로 서버와 함께 작성된 대칭키 를 서로에게 전달합니다. 이때 중간 공격자는 서버의 개인키 를 알고있지 않는한 내용을 복호화하지 못하여 데이터 해독이 불가능 합니다.

이렇게 서로 안전하게 대칭키 가 전달되었다면, 암-복호화가 빠른 대칭키 로 데이터 통신을 합니다.

SSL 통신 절차

TCP와 같은 연결지향 프로토콜은 크게 아래의 과정을 거칩니다.

  • 악수(HandShake)
  • 데이터 전송(세션)
  • 세션 종료

SSL 통신도 결국 TCP위에서 동작하므로, 위 과정과 같습니다만, 세부적인 내용이 조금 다릅니다.

SSL 통신은 TCP의 핸드쉐이크 (SYNSYN ACKACK) 과정이 이루어 진 후에, SSL 통신이 시작됩니다. (악수 → 데이터 전송 → 세션 종료)

악수(HandShake)

  1. Client Hello (클라이언트가 서버에 접속합니다. )
    • 서버에게 평문 문자열 Client Hello 를 전송합니다.
    • 서버에게 대칭키 를 만들 수 있는 랜덤 데이터를 평문으로 전송 합니다.
  1. Server Hello (서버가 Client Hello 를 받은 후, 클라이언트에게 응답합니다.)
    • 클라이언트에게 평문 Server Hello 를 전송합니다.
    • 클라이언트에게 대칭키 를 만들 수 있는 랜덤 데이터를 평문으로 전송합니다.
    • 제일 중요한 SSL 인증서 를 전송합니다.
  1. 클라이언트의 SSL 인증서 신뢰성 판단
    • 서버에게 받은 SSL 인증서 를 보유하고 있는 CA 리스트를 통해 복호화 합니다.
    • 복호화 에 성공하였다면, 해당 서버를 신뢰할 수 있다고 판단합니다.
  1. 서버에 대칭키 전송 (SSL 핸드쉐이크의 핵심 목적 입니다.)
    • 클라이언트는 본인이 만든 랜덤 데이터와 서버에서 받은 랜덤 데이터를 이용하여, 대칭키 를 구성합니다.
    • 해당 대칭키를 SSL 인증서 에 포함되어 있는 서버 공개키암호화 하여 서버에게 전송합니다.
  1. 핸드쉐이크 종료
    • 클라이언트와 서버가 서로 대칭키 를 안전하게 전달 받은 후, 통신 준비가 되었다는 신호와 함께 핸드쉐이크가 종료됩니다.

데이터 전송(세션)

서버와 클라이언트가 데이터를 서로 주고 받고 하는 단계입니다. 서로 안전하게 전달받은 대칭키 를 사용하여, 암-복호화를 빠르게 진행합니다.

세션종료

데이터 전송이 끝나면 SSL 통신이 끝났음을 서로에게 알려줍니다.

오늘 준비한 포스팅은 여기까지 입니다. 읽어주셔서 감사합니다.

'네트워크' 카테고리의 다른 글

[네트워크] REST API  (0) 2021.08.08
[네트워크] OSI 7계층  (0) 2021.07.26

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts