본문 바로가기
Back-End/Spring Security

[HTTPS] 인증 및 보안 (feat. 공개키와 대칭키)

by 달의 조각 2022. 9. 20.

HTTP와 HTTPS

Hyper Text Transfer Protocol Secure Socket layer

 

  HTTP란 인터넷에서 데이터를 주고받을 수 있는 통신 프로토콜을 말하며, 80포트를 사용하고 있다.

TCP/IP 위에서 동작하며 확장이 가능하다. 오늘날 하이퍼텍스트 문서 뿐만 아니라 이미지, 비디오, HTML 폼 결과와 같은 내용을 서버에 POST 하기 위해서도 사용된다. Stateless이기 때문에 이전 통신에 대한 정보를 기억하지 않으며, Conectionless 특성 또한 가져서 서버가 요청에 대한 응답을 마치면 연결을 끊는다.

암호화되지 않은 평문 데이터를 전달하는 프로토콜이기 때문에 기밀한 정보를 주고받기에는 적절하지 않다. 따라서 HTTPS가 등장했다.

  HTTPS는 SSL 혹은 TLS라는 알고리즘을 이용해서 HTTP 프로토콜 내용을 암호화하여 전송한다. 443포트를 사용하며, 네트워크 상에서 중간에 제3자가 정보를 볼 수 없도록 지원한다. 모든 HTTP 요청과 응답 데이터는 네트워크로 보내지기 전에 암호화된다.

 

🌳 암호화

  서버와 클라이언트가 주고받는 정보를 제3자가 탈취할 수 없도록 한다.

대칭키

  양쪽이 공통의 비밀키를 공유한다.(= 암복호화 시에 사용하는 키가 동일하다.) 해당 키를 아는 사람만이 문서를 복호화해서 볼 수 있다. 대칭키를 주고받을 때에는 비대칭키로 주고받는다. 대표적으로 DES, 3DES, AES, SEED, ARIA 알고리즘이 있다.

수행 시간이 짧다는 장점이 있으나 키를 교환해야 한다는 문제(키 배송 문제)가 발생한다. 사람이 증가할수록 키의 관리가 어려워진다. 키를 교환하는 과정에서 탈취 가능성이 존재하고, 사람이 증가할수록 전부 따로따로 교환이 이뤄지므로 관리해야 하는 키가 방대하게 많아진다. 이 문제를 해결하기 위해 키를 사전 공유하거나 키 배포 센터를 의한 해결, 공개키 암호에 의한 방법을 택할 수 있다.

공개키(비대칭키)

  암복호화에 사용하는 키가 서로 다르다. (= 각각 공개키와 비밀키를 가지고, 상대가 공개키로 암호화한 데이터를 비밀키로 복호화한다.) 대칭키의 키 교환 문제를 해결하기 위해서 등장했다.

송수신자 모두 한 쌍의 키를 가진다. 키가 공개되어 있기 때문에 키를 교환할 필요가 없다. 공개키는 모든 사람이 접근 가능하며, 개인키는 각 사용자만이 가지고 있는 키이다. 예를 들어, A가 B에게 데이터를 보낸다고 할 때, A는 B의 공개키로 암호화한 데이터를 보내고 B는 본인의 개인키로 해당 암호화된 데이터를 복호화해서 보기 때문에 암호화된 데이터는 B의 공개키에 대응되는 개인키를 갖고 있는 B만이 볼 수 있게 된다.

키 교환이 불필요하며, 기밀성을 제공한다는 장점이 있다. (인증 기능으로도 활용 가능) 대칭키 암호화 방식에 비해 속도가 느리다는 단점이 있다.

 

🌳 인증서

  SSL 인증서는 클라이언트와 서버와의 통신을 제3자(CA)가 보증해 주는 전자화된 문서이다. 클라이언트가 서버에 접속한 직후, 서버는 클라이언트에게 이 인증서를 전달하면 브라우저는 해당 인증서 정보가 신뢰할 수 있는 것인지 검토한 뒤 다음 절차를 수행한다.

CA(Certificate Authority)공인 인증서 발급 기관이다. 서버의 공개키와 정보를 CA의 비밀키로 암호화하여 인증서를 발급한다. CA 공개키로 복호화가 가능하다.

SSL과 SSL 디지털 인증서를 이용했을 때의 이점

  • 통신 내용이 공격자에게 노출되는 것을 막을 수 있다.
  • 클라이언트가 접속하려는 서버가 신뢰할 수 있는지 판단할 수 있다.
  • 통신 내용의 악의적인 변경을 방지할 수 있다.

SSL 인증서의 내용

서버 측의 공개키나 도메인 등은 인증서를 발급받을 때 CA에 제출해야 한다.

  • 서비스의 정보(인증서를 발급한 CA, 서비스 도메인 등)
  • 서버 측 공개키(공개키의 내용, 공개키의 암호화 방법)

SSL 인증서의 발급 과정

  1. 서버가 클라이언트에게 CA 인증서(서비스 정보와 공개키)를 전달한다.
  2. 클라이언트는 OS나 브라우저의 CA 리스트로 브라우저에서 인증된 CA에서 발급받은 인증서인지 확인한다.
  3. 인증서가 확인되었다면 서명을 복호화해 얻은 CA 기관의 공개키로 서버 인증서를 복호화한다.
  4. 인증서의 도메인과 데이터를 제공하는 서버의 도메인을 비교할 수 있으므로 '중간자 공격'을 감지하여 보호할 수 있다.

 


 

HTTP 사설 인증서 발급 및 서버 구현

 

🌳 Java가 지원하는 인증서 형식

  1. PKCS12(Public Key Cryptographic Standards #12): 여러 인증서와 키를 포함할 수 있으며, 암호로 보호된 형식이다.
  2. JKS(Java KeyStore): PKCS12와 유사하다. 독점 형식이며, Java 환경으로 제한된다.

 

🌳 mkcert 설치 - PKCS12

Window: WSL 터미널

$ sudo apt install libnss3-tools
$ wget -O mkcert <https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64>
$ chmod +x mkcert
$ sudo cp mkcert /usr/local/bin/

설치 안 될 때 아래 명렁어 실행 후 다시 설치
$ sudo apt update
로컬을 인증된 발급 기관으로 추가하기
$ mkcert -install

PKCS12 인증서 생성
$ mkcert -pkcs12 localhost

저장 경로: \\wsl.localhost\Ubuntu\home\yujung

로컬 환경(내 컴퓨터)에 신뢰할 수 있는 인증서를 만든다.

 

🌳 설정에 인증서 정보 추가

server.ssl.key-store=classpath:localhost.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=changeit

생성된 인증서는 resources 폴더로 옮긴 후 application.properties에 설정을 추가한다.

 


 

Hashing

 

🧂 암호화

  일련의 정보를 알고리즘을 이용해서 다른 형태로 변환하여 정보를 관리한다.

클라이언트가 전달한 패스워드를 서버에서 암호화를 시킨 후 DB에 저장된 유저 정보와 대조한다. DB는 패스워드를를 원본으로 저장하지 않고 어떤 알고리즘을 거친 결과를 저장한다.

해커가 악의적으로 DB에서 패스워드를 탈취한다고 알고리즘을 모르는 해커는 유저의 진짜 비밀번호를 모르기 때문에 다른 사이트에서 유사한 패턴을 시도하는 것을 막을 수 있다.

 

🧂 Hashing과 Salt

  해싱이란 Key값을 해시 함수에 대입하여 나온 결과를 주소로 사용하여 Value에 접근할 수 있도록 하는 방법이다. (ex. SHA1, SHA256) 최대한 다른 해시값과의 중복을 피해야 하며, 아주 작은 단위의 변경이라도 완전히 다른 값을 가져야 한다.

회원 가입 요청이 오면 입력받은 패스워드를 해시 알고리즘을 이용해 변환한 후 DB에 저장한다. 로그인이나 인증이 필요한 요청이 들어오면 입력받은 패스워드를 해시값으로 바꾸고 DB의 값과 비교한다.

  Salt란 암호화 해야 하는 값에 별도의 값을 추가해서 결과를 변형시킨다.

같은 문자열은 같은 해시 값을 가지기 때문에 해시값과 원래 값을 레인보우 테이블에 저장하여 Decoding 할 수도 있다. 원본 값에 Salt를 거치면 기존 해시값과는 다른 값이 반환되어 원본 값을 보호할 수 있다.

유저와 패스워드 별로 유일한 값을 가져야 하며, 재사용하지 말아야 한다. DB의 유저 테이블에 함께 저장된다.

 

 

HTTP 헤더1 - 일반 헤더: 인증

 

cookiee.tistory.com

댓글