보안 - HTTPS 통신/암호화

박채은·2023년 1월 12일
0

Spring

목록 보기
29/35

인증/보안

  • 인증(Authentication): 암호화를 통해 사람의 정체를 확인하는 과정
  • 인가(Authorization): 권한 부여
  • 보안(Security): 정보를 여러 위협으로부터 보호하는 것

HTTP

  • 인터넷에서 데이터를 주고받을 수 있는 프로토콜
  • Stateless한 성질을 가지고 있다.

Stateless

  • HTTP 통신에서 서버는 클라이언트의 상태를 저장하지 않는다.
    -> 매번 통신할 때마다, 서버는 해당 클라이언트와 처음 만나는 것처럼 반응하게 된다.

  • Stateless의 반대 = Stateful

HTTPS

  • Hyper Text Transfer Protocol Secure Socket layer
  • HTTP + S
    • HTTP over SSL/TLS
    • HTTP over Secure
  • HTTP 통신을 하는 과정에서 데이터를 암호화해서 주고받는 방법
  • 기밀성과 무결성을 갖는다.
    • 기밀성(privacy): 메세지를 가로챌 수 없다.
    • 무결성(integrity): 메세지를 조작할 수 없다.(수정 x)

HTTPS는 인증서, CA, 비대칭 키 암호화를 사용한다!
비대칭 키 암호화에는 2가지 방법이 있는데, 상황에 맞게 2가지 방법을 모두 사용한다.(자세한 건 아래에서 설명해뒀다.)


SSL/TLS

  • 서버와 클라이언트 간의 CA를 통해서 서버를 인증하는 과정에서 데이터를 암호화해주는 프로토콜
  • SSL과 TLS은 사실상 동일한 프로토콜으로, SSL이 표준화되어 이름이 바뀐 것이 TLS

암호화

정보를 임의의 방식을 사용해서 다른 형태로 변환하는 것
정보를 소유한 사람을 제외하고는 알 수 없도록 "알고리즘"을 통해 정보를 관리하는 것

암호화에는 크게 (1) 대칭키 암호화, (2) 비대칭키 암호화, (3) 해시가 있다.


대칭키/비대칭키 암호화

서버와 클라이언트가 데이터를 주고 받을 때, 제 3자가 중간에서 데이터를 탈취할 수도 있다.
이를 방지하기 위해서 서버와 클라이언트는 서로 합의한 방법으로 데이터를 암호화해서 주고 받는다.

HTTP는 중간에 데이터가 탈취된다면, 데이터의 내용이 그대로 노출되는데 HTTPS는 암호화를 했기 때문에 탈취되더라도 데이터의 내용을 알아보지 못한다.

HTTPS에서는 비대칭 키대칭키 방식을 혼용해서 암호화를 사용한다.

  • 공개키 = public key ➡️ 모두에게 공개된 키
  • 비밀키 = 개인키 = private key ➡️ 아무에게도 공개하지 않음!
    => 공개키와 비밀키는 언제나 한 쌍이다!
  • 대칭키
    • 양쪽이 동일한 비밀키를 갖는다.
    • 동일한 비밀키를 사용해서 암호화/복호화한다.
  • 비대칭 키
    • 양쪽이 모두 공개키와 비밀키를 갖는다.
    • 공개키로 암호화, 비밀키로 복호화 ➡️ 암호화
    • 비밀키로 암호화, 공개키로 복호화. ➡️ 전자서명

대칭키는 집 대문을 생각하면 될 것 같다.
대문은 동일한 하나의 키로 열 수 있고 잠글 수 있다.
가족이 아닌 다른 사람에게는 누구에게도 키를 공유하지 않고, 해당 키를 다른 사람이 갖게 된다면 집이 털릴 수도 있다.


대칭키의 한계

클라이언트와 서버가 데이터를 주고받을 때는 대칭키를 사용한다.
그 이유는 대칭키보다 비대칭 키 알고리즘이 더 어렵기 때문에 컴퓨터에 부담을 주게 되기 때문이다.
(데이터를 주고 받는 것은 매우 빈번하기 때문에)

이때 어떤 대칭키(비밀키)를 쓸지를 서버와 클라이언트가 알아야 하기 때문에 데이터와 함께 대칭키를 서로 주고 받게 된다.
이 주고 받는 과정에서 대칭키(비밀키)가 노출될 수 있고 해당 대칭키로 암호화된 데이터를 무조건 복호화할 수 있기 때문에 문제가 발생한다.

대칭키를 주고 받을 때는 절대 대칭키가 노출되서는 안 된다!
따라서 대칭키를 서버와 클라이언트가 주고 받을 때 비대칭 키 방식을 사용한다.

결론) 대칭키를 비대칭키로 비밀리에 보내고, 그 이후부터는 대칭키를 사용해서 소통하게 된다.


비대칭키

비대칭 키는 2가지 암호화 방법이 있다.

  1. 공개키로 암호화, 비밀키로 복호화 ➡️ 암호화
  2. 비밀키로 암호화, 공개키로 복호화 ➡️ 전자서명

1. 공개키로 암호화, 비밀키로 복호화

A라는 사람이 공개키와 비밀키 한 쌍을 생성한다.
공개키는 누구에게나 공개되는 키이고, 비밀키는 누구에게도 공개되지 않는 키이다.

따라서 공개키를 공개한다!
그러면 나와 데이터를 주고 받을 B도 공개키를 받게 되고, 제3자도 공개키를 받게 된다.

우선 B는 A의 공개키를 사용해서 자신의 데이터를 암호화해서 A에게 보낸다.
해당 공개키를 사용해서 암호화된 데이터는 A가 가진 비밀키로만 복호화할 수 있다. A가 가진 비밀키는 절대 공개되지 않으므로 제3자가 아무리 암호화된 데이터에 접근한다해도 비밀키가 없으므로 복호화할 수 없는 것이다!
(B도 암호화는 할 수 있지만, 비밀키가 없어서 복호화를 못할 것이다.)

즉, 이 방법은 데이터를 암호화하는 것이 목표로 비대칭 키의 암호화라고 볼 수 있다.

2. 비밀키로 암호화, 공개키로 복호화

공개키는 누구에게나 공개되기 때문에 모든 사람들이 복호화할 수 있다.
그럼 "보안의 의미가 없지 않나?"라고 생각할 수 있는데 맞다!

2번은 보안으로써의 기능이 아니라 전자 서명처럼 데이터 제공의 신원을 보장해주는 역할을 한다.
(공인인증체계의 기본 바탕이 되는 전자 서명)

A가 비밀키로 암호화한 것을 공개키와 함께 B에게 전송한다.
B는 암호화된 데이터를 공개키로 복호화할 수 있고, 이는 해당 공개키와 쌍을 이루는 비밀키에 의해서 암호화 되었다는 것을 의미한다.

즉 데이터 제공자의 신원 확인이 보장된다.


[참고]
https://spidyweb.tistory.com/310


인증서

  • 데이터를 전송한 서버가 정말 데이터를 전송한, 신뢰할 수 있는 서버인지 인증할 때 사용한다.
    ➡️ 서버의 신원을 보증해주는 역할
  • 서버는 서버의 공개키, 정보(도메인 정보 등)를 인증서에 담아 발급한다.
  • 서버가 클라이언트에게 요청을 받으면, 응답과 함께 인증서를 전달한다.
  • 브라우저는 HTTPS를 사용하면 서버가 전달한 인증서를 확인할 수 있다.
  • 인증서를 통해 중간자 공격으로부터 클라이언트를 보호할 수 있다.

CA (Certificate Authority)

  • 인증서를 발급해주는 공인된 기관
  • 인증서는 CA의 비밀키로 암호화되고 CA의 공개키로 복호화할 수 있다.
    => 누구나 CA의 공개키를 사용해서 인증서를 복호화할 수 있다.
    => 복호화 되었다는 것은 인증서가 해당 CA에서 발급한 인증서라는 것을 보증해준다.

HTTPS 통신 과정

인증서 발급

1) 서버가 공개키와 비밀키를 생성한다.
2) 서버는 CA에 "서버의 공개키"와 "서버의 정보"를 전송해서 인증서를 발급받는다.
(인증서에는 서버의 공개키가 포함됨)

3) 인증서를 암호화하기 위해서 CA의 공개키, 비밀키를 생성한다.
4) CA의 비밀키로 인증서를 암호화한다.
5) 인증서를 서버에게 전송한다.

client hello & server hello

6) 서버 - 클라이언트 Hand Shake

  • Client Hello: Client -> Server
  • Server Hello: Server -> Client

7) 서버가 클라이언트에게 인증서를 전달
8) 클라이언트가 서버의 인증서를 검증한다.
8-1) 클라이언트는 브라우저에 내장되어 있던 CA 리스트와 인증서를 발급한 CA를 비교한다.
-> 인증서의 도메인과 서버의 도메인을 비교

8-2) CA 리스트에 존재하는 인증된 CA가 아니라면, 화면에 경고창을 띄운다.
8-3) 인증된 CA라면, 클라이언트는 CA의 공개키를 사용해서 인증서를 복호화한다.
(CA의 공개키는 CA 리스트에 함께 존재한다.)
8-4) 복호화가 잘 되었다면 클라이언트는 해당 서버를 신뢰할 수 있는 서버로 생각한다.(인증서 검증 성공!)

9) 클라이언트는 이제 서버를 신뢰하게 된다. 서버와 데이터를 주고 받을 때 사용할 비밀키(대칭키)를 생성한다.

10) 클라이언트가 서버에게 비밀키를 전달하기 위해서, 서버의 공개키(비대칭키)비밀키(대칭키)를 암호화한다. → 비대칭키 사용
(서버의 공개키는 인증서를 통해서 얻었음)

11) 서버는 클라이언트에게 암호화된 비밀키(대칭키)를 받는다.
12) 서버의 비밀키(비대칭키)로 암호화된 클라이언트의 비밀키(대칭키)를 복호화한다.

=> 서버와 클라이언트가 모두 동일한 대칭키(비밀키)를 갖게 되므로 통신할 준비가 완료된다!


해싱

문자열을 임의의 연산을 적용해서 다른 문자열로 변환하는 것

대표적인 해시 알고리즘으로는 SHA-256이 있다.
SHA-256은 원본 데이터의 길이와 관계없이 항상 256 비트(64 자리의 문자열)의 해시값을 리턴한다.

왜 256 비트인데 64 글자인가?
16진수로 문자를 표현해서 1 문자당 4 bit이기 때문에

해싱의 철칙

  1. 해시값을 계산하는데 오래걸리지 않아야 한다.
    -> 해시값을 만드는 것은 오래 걸리면 안되지만, decoding 하는 것은 오래 걸려야 한다.
    -> 해싱하는데 오래 걸리면 로그인 할 때마다 엄청 기다리게 된다!

  2. 모든 값은 고유한 해시값을 가져야 한다.
    -> 하지만 해시는 수학적 연산이기 때문에 낮은 확률이지만 똑같은 해시 값을 가질 수도 있다.

  3. 아주 작은 단위의 변경이라도 완전히 다른 해시값을 가져야 한다.

Salt

암호화 해야하는 값에 별도의 값을 추가하여 결과를 변형시키는 것

해시는 수학적 연산이기 때문에, 어떤 값을 넣었을 때 항상 같은 해시값을 가진다.
제3자가 악의적으로 원본 값과 해시값을 대조한 테이블(레인보우 테이블)을 통해서 해시 알고리즘을 알아낼 수 있고, 그렇게 되면 암호화된 데이터들을 탈취해서 데이터를 알아낼 수 있을 것이다.

그렇기 때문에 원본 데이터에 Salt를 추가한 후에 해싱한다면, 해싱 알고리즘이 노출되더라도 원본 데이터를 보호해줄 수 있다.

Salt 사용 시 주의사항

  1. Salt는 유일한 값을 가져야 한다.
  2. 사용자가 데이터를 변경할 때마다, 새로운 Salt를 사용해야 한다.
    → 비밀번호를 변경할 때도 매번 새로운 Salt를 사용함
  3. Salt는 재사용되지 않아야 한다.
  4. Salt는 DB의 유저 테이블에 같이 저장되어야 한다.

[참고]
https://opentutorials.org/course/228/4894

[나중에 더 자세히 읽어볼 블로그]
https://nuritech.tistory.com/25
-> HTTPS 통신에 대해서 매우 잘 정리해두셨다.

0개의 댓글