❑ HTTPS
HTTPS = HTTP + Secure
HTTP 프로토콜 내용을 암호화 ➡️ 보안성 추가
(기존 HTTP 방식은 전송도중 누군가 요청을 들여다보려고 하면 볼 수 있었다.)
➤ HTTPS 란?
- Hyper Text Transfer Protocol Secure Socket layer
- HTTP over SSL(TLS), HTTP over Secure 라고 부르기도 한다.
- HTTP 요청을 SSL 혹은 TLS(Transfer Layer Security) 라는 알고리즘을 이용해 HTTP 통신을 하는 과정에서 데이터를 암호화해서 전송하는 방식이다.
➤ HTTPS의 목적
▶️ 암호화
- 제3자가 서버와 클라이언트가 주고받는 데이터를 탈취하여 알아볼 수 없도록 한다.
- 서버와 클라이언트가 서로 합의한 방법으로 데이터를 암호화하여 주고받는다.
- 비대칭키 방식과 대칭키 방식을 혼용해서 사용
✅ 대칭키와 비대칭키
▶️ 대칭키
- 양쪽이 공통의 비밀 키를 공유하여 데이터를 암호화 및 복호화하는 것을 말한다.
- 암호화와 복호화에 같은 암호키를 사용하는 알고리즘이다.
▶️ 비대칭키
- 암호화할 때와 복호화할 때의 키가 서로 다른 키를 가진 방식을 말한다.
- 대칭키 알고리즘보다 훨씬 복잡하다.
- 공개키(public key)와 개인키(private key)가 하나의 쌍을 이룬다.
- 공개키 : 다른 사람들에게 공개된 키로 정보를 암호화할 수 있다.
- 개인키 : 사용자 본인만 알고 있어서 암호를 풀 수 있다.
- 공개키로 암호화하는 경우는 데이터 보안에 중점을 둔 것
- 개인키로 암호화하는 경우는 전자서명같은 인증 과정에 중점을 둔 것
- 비대칭키 대표 알고리즘: RSA, Diffie-Hellman(디피-헬만), 타원곡선암호(ECDSA)
▶️ 인증서
- 브라우저가 서버의 응답과 함께 전달된 인증서를 확인할 수 있다.
- 인증서 : 서버의 신원을 보증하여 접속한 사이트가 해커가 정교하게 따라한 가짜 사이트가 아님을 보장해주는 역할
- Certificate Authority(CA) : 인증서를 발급해주는 엄격하게 공인된 기관, 보증할 수 있는 제3자
- 서버의 공개키와 정보를 CA의 비밀키로 암호화하여 인증서를 발급한다.
- 서버가 클라이언트에 CA에서 발급받은 인증서를 전달 ➡️ 클라이언트는 OS또는 브라우저에 미리 내장되어 있던 CA 리스트를 통해 인증된 CA에서 발급받은 인증서인지 먼저 확인한다.
- 인증된 CA에서 발급한 인증서가 아니라면 브라우저에서 “NET::ERR_CERT_AUTHORITY_INVALID” 경고창을 띄워 서버와 연결이 안전하지 않다고 알려준다.
- 클라이언트에서 인증서 확인 ➡️ 브라우저에 제공된 해당 CA 기관의 공개키로 서버 인증서를 복호화
- 서명을 복호화해 얻은 공개키로 클라이언트가 서버를 믿을만한 대상인지 신뢰할 수 있다.
- 만약 위조된 인증서라면 CA의 공개키로 인증서를 복호화할 수 없다. ➡️ 중간자 공격을 예방할 수 있다.
- 서버와 클라이언트 간의 CA를 통해 서버를 인증하는 과정과 데이터를 암호화하는 과정을 아우른 프로토콜을 TLS 또는 SSL 이라고 한다. (SSL과 TLS는 동일한 규약을 뜻하지만 SSL이 표준화되며 바뀐 이름이 TLS 이다.)
※ 중간자 공격(Man In The Middle Attack)
중간자 공격(man in the middle attack, MITM)은 네트워크 통신을 조작하여 통신 내용을 도청하거나 조작하는 공격 기법이다.
통신을 연결하는 두 사람 사이에 중간자가 침입하여 두사람은 상대방에게 연결했다고 생각하지만 실제로는 두 사람은 중간자에게 연결되어 있으며 중간자가 한쪽에서 전달된 정보를 도청 및 조작한 후 다른 쪽으로 전달한다.
암호 프로토콜은 중간자 공격을 막기 위해 인증을 사용한다.
예를 들어 TLS/SSL 프로토콜은 공개키를 기반으로 한 인증을 사용한다.
▶️ 자바에서 지원하는 인증서 형식
1. PKCS12 (Public Key Cryptographic Standards #12) : 여러 인증서와 키를 포함할 수 있으며 암호로 보호된 형식이다. 업계에서 널리 사용한다.
2. JKS(Java KeyStore) : PKCS12와 유사하다. 독점 형식이며 Java 환경으로 제한된다.
❑ Hashing
➤ Hashing 이란?
어떠한 문자열에 임의의 수학적 연산(알고리즘)을 적용하여 다른 문자열로 변환하는 것
➡️ 제3자(해커)가 DB를 해킹하여 탈취한 데이터의 원본을 알 수 없게 만들어 데이터를 보호한다.
대표적 해시 알고리즘 : SHA1, SHA256
➤ Encryption(암호화)
일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람을 제외하고 이해할 수 없도록 알고리즘을 이용해 정보를 관리하는 과정
➤ Hashing을 적용할 때 철칙
1. 모든 값에 대해 해시 값을 계산하는데 오래걸리지 않아야 한다.
- 해시값을 해독(decoding)할 때는 많은 시간이 걸려야하지만 해시값을 만들 때는 오래걸리지 않아야 한다.
2. 최대한 해시 값을 피해야 하며, 모든 값은 고유한 해시값을 가진다.
- Hashing은 어떠한 수학적 연산을 통해 문자열을 변환시켜주기 때문에 극히 낮은 확률로 전혀 다른 문자열임에도 똑같은 해시값을 가지는 경우가 존재한다.
- 이러한 상황이 최대한 발생하지 않도록 하는 알고리즘들이 이미 배포되어 있기 때문에 그 알고리즘들을 사용할 수 있다.
3. 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.
- 부분이 변경되어도 해시값으로는 추측할 수 없도록 완전히 다른 값을 반환해야 한다.
➤ Authentication (인증)
회원가입 시 비밀번호와 같이 알려지면 안되는 정보는 해시 알고리즘을 이용해 복잡하고 긴 문자열(해시값)으로 변환하여 DB에 저장한다. 이후 인증이 필요한 요청이 들어오면 입력받은 비밀번호를 해시값으로 바꾸고 DB에 저장되어있는 해시값과 비교한다.
➤ Salt
암호화해야 하는 값에 어떤 ‘별도의 값’을 추가하여 결과를 변형하는 것
암호화만 해놓았을 때 안전해보이지만 특정 알고리즘을 통한 해시는 결과가 항상 같기 때문에 해시된 값과 원본 값을 대조한 테이블(레인보우 테이블)이 있다면 쉽게 원본 비밀번호를 알아내는 것이 가능하다.
➡️ 이를 보완하기 위해 기존 문자열에 개발자만 아는 Salt값을 추가한 후 Hashing 한다면 해커가 예상하기 힘든 전혀 다른 문자열이 만들어진다.
Salt를 이용하면 Hashing 만 했을 때보다 더욱 강력하고 안전하다.
※ 참고) 레인보우 테이블
- 해시함수(MD-5, SHA-1, SHA-2 등)를 사용하여 만들어낼 수 있는 값들을 대량으로 저장한 표이다.
- 해시함수를 이용하여 저장된 비밀번호로부터 원래 비밀번호를 추출하는데 사용한다.
▶️ Salt 사용 시 주의점
1. Salt 는 유저와 패스워드 별로 유일한 값을 가져야 한다.
2. 사용자 계정을 생성할 때와 비밀번호를 변경할 때마다 임의의 Salt를 사용해서 Hashing해야 한다.
3. Salt는 절대 재사용하지 말아야한다.
4. Salt는 DB의 유저 테이블에 같이 저장되어야 한다.
❑ Cookie
➤ Cookie 란?
어떤 웹사이트에 들어갔을 때, 서버가 일방적으로 클라이언트에 전달하는 작은 데이터
- 서버가 웹 브라우저에 정보를 저장하고 불러올 수 있는 수단
- 해당 도메인에 대해 쿠키가 존재하면, 웹 브라우저는 도메인에게 http 요청시 쿠키를 함께 전달한다.
- 쿠키를 이용하는 것 : 서버에서 클라이언트에 쿠키를 전송하는 것 + 클라이언트가 서버로 쿠키를 전송하는 것
- 데이터(쿠키)를 저장한 이후 아무때나 가져올 수는 없고 저장한 이후 특정 조건들이 만족하는 경우에만 다시 가져올 수 있다. ➡️ 쿠키 옵션으로 설정
- HTTP 요청은 stateless (무상태) 이지만 상태를 유지할 수 있게 해준다.
➤ Cookie 이용법
사용자 선호, 테마 등 장시간 보존해야하는 정보 저장에 적합하다.
로그인을 위한 인증정보를 저장하기도 한다.
인증정보 같이 민감한 정보는 Hashing 되어서 저장된다.
웹사이트에 들어갔을 때 “장치에 쿠키를 저장하시겠습니까?”
➡️ 회사가 필요한 마케팅 정보등을 쿠키에 저장하는 경우도 많다.
➤ Cookie 전달 방법
서버가 응답 헤더에 Set-Cookie 라는 property에 쿠키의 이름, 값, 경로 등의 옵션을 전달
클라이언트는 Set-Cookie 를 확인한다.
클라이언트는 매 요청시 마다 쿠키를 전달한다.
서버는 쿠키내용을 바탕으로 무언가 일을 한다.
Set-Coookie property에는 다양한 옵션을 담아서 전송할 수 있다.
➤ Cookie Options
▶️ Domain
도메인 옵션과 서버의 도메인이 일치할 때만 쿠키를 전송할 수 있다.
➡️ 서로 다른 도메인 주소에서 쿠키를 전송하는 것을 방지한다.
▶️ Path
서버와 요청의 세부경로가 일치하는 경우 쿠키 전송
세부경로 : 서버가 라우팅할 때 사용하는 경로
옵션에 설정된 path를 전부 만족하는 경우 요청하는 Path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있다.
명시하지 않으면 기본으로 ‘ / ‘ 으로 설정되어 있다.
▶️ MaxAge or Expires
쿠키가 유효한 기간을 정하는 옵션이다.
만약 쿠키가 영원히 남아있다면 탈취하기 쉬워지기 때문에 유효기간을 설정하는 것이 보안 측면에서 중요하다.
MaxAge : 앞으로 몇 초 동안 쿠키가 유효한지 설정하는 옵션이다.
Expires : 언제까지 유효한지 Date를 지정한다. 클라이언트의 시간을 기준으로 지정된 시간, 날짜를 초과하면 쿠키는 자동으로 파괴된다.
위 옵션 여부에 따라 세션 쿠키(Session Cookie)와 영속성 쿠키(Persistent Cookie)로 나눠진다.
- 세션 쿠키 : MaxAge 또는 Expires 옵션이 없는 쿠키, 브라우저가 실행 중일 때만 사용할 수 있는 임시 쿠키이다. 브라우저를 종료하면 해당 쿠키는 소멸된다.
- 영속성 쿠키 : 브라우저의 종료 여부와 상관없이 MaxAge 또는 Expires에 지정된 유효시간만큼 사용가능한 쿠키이다.
▶️ HttpOnly
true : 자바스크립트에서 쿠키에 접근이 불가능
default : false 로 지정
쿠키는 <script> 태그로 접근 가능 ➡️ XSS 공격에 취약
HttpOnly 옵션을 주면 스크립트 태그로 접근을 불가능하게 만들어서 보안을 향상시킬 수 있다.
▶️ Secure
쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키전송 여부를 결정한다.
true : HTTPS 프로토콜을 이용한 통신의 경우에만 쿠키를 전송할 수 있다.
▶️ SameSite
CORS 요청의 경우 옵션 및 메서드에 따라 쿠키 전송 여부 결정
CSRF 공격을 막는데 효과적인 옵션
Cross-Origin 요청을 받은 경우 요청에서 사용한 메서드와 해당 옵션(GET, POST, PUT, PATCH, ...)의 조합으로 서버의 쿠키 전송 여부를 결정하게 된다.
사용가능한 옵션
- Lax : Cross-Origin 요청이면 ‘GET’ 메서드에 대해서만 쿠키를 전송할 수 있다.
- Strict : Cross-Origin 이 아닌 same-site 인 경우에만 쿠키를 전송할 수 있다.
- None : 모든 메서드 요청에 대해 쿠키 전송 가능, none 옵션은 Secure 쿠키 옵션이 필요하다.
same-site 는 요청을 보낸 origin과 서버의 도메인, 프로토콜, 포트가 같은 경우를 말한다. 이중 하나라도 다르면 Cross-Origin으로 구분된다.
➤ 쿠키를 이용한 상태 유지
서버는 쿠키의 특성을 이용하여 클라이언트에 인증정보를 담은 쿠키를 전송하고 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless 한 HTTP 통신을 Stateful 하게 유지할 수 있다.
하지만 쿠키는 오랜시간 유지될 수 있고, 자바스크립트를 이용해 쿠키에 접근할 수 있기 때문에 민감한 정보를 담는 것은 위험하다.
인증정보를 탈취하여 서버에 요청을 보낸다면 서버는 누가 요청을 보낸 건지 상관하지 않고 인증된 유저의 요청으로 보기 때문에 개인정보같은 민감한 정보에 접근이 가능하다.
※ 참고) CSRF(사이트 간 요청 위조, Cross-Site Request Forgery)
- 웹사이트 취약점 공격중 하나
- 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 해킹 공격이다.
- 특정 웹사이트가 사용자의 웹 브라우저를 신용하는 상태를 노린 공격이다.
- 사용자가 웹사이트에 로그인한 상태에 사이트 간 요청 위조 스크립트가 삽입된 페이지를 열면 공격 대상이 되는 웹사이트는 위조된 공격 명령이 믿을 수 있는 사용자로부터 발송된 것으로 판단하게 되어 공격에 노출된다.
- CSRF는 개별 링크와 폼이 사용자 별로 예측 가능한 토큰을 사용할 때 발생한다. 예측 불가능한 토큰이 있다면 공격자는 요청 메시지를 변조할 수 없지만 예측 가능한 토큰이 있다면 요청 메시지를 변조할 수 있다.
- 대안 : 리퍼러(Refere) 체크, 시큐리티 토큰(Security Token) 사용, 더블 서밋 쿠키(Double Submit Cookie) 검증
※ 참고) XSS(cross-site scripting, 사이트 간 스크립팅)
- 웹 애플리케이션에서 많이 나타나는 취약점
- 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다.
- 주로 여러 사용자가 보는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다.
- 웹 애플리케이션이 사용자로부터 입력받은 값을 제대로 검사하지 않고 사용할 경우 나타난다.
- 이 취약점은 해커가 사용자의 쿠키, 세션 등의 정보를 탈취하거나 자동으로 비정상적인 기능을 수행하게 할 수 있다.
- 대안 : 입출력 값 검증 및 무효화(XSS 공격은 기본적으로 <script> 태그를 사용하기 때문에 태그 문자 등 위험한 문자입력 시 문자 참조로 필터링하고 서버에서 브라우저로 전송시 문자를 인코딩 한다.)
※ 참고) CORS (교차 출처 리소스 공유, Cross-Origin Resource Sharing)
- 추가 HTTP 헤더를 사용하여 한 출처(도메인, 프로토콜, 포트)에서 실행중인 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.
- 웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차 출처 HTTP 요청을 실행한다.
※ 참고) same-origin
같은 origin 은 URI 스키마, host name, 포트 넘버가 같은 것을 말한다.
클라이언트 측면에서 데이터의 기밀성과 일관성을 잃지 않기 위해서 관련없는 사이트가 공급하는 컨텐츠 사이에 엄격하게 분리한다.
Set-Cookie 참고자료
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
리눅스 명령어
xargs
https://ko.linux-console.net/?p=229
'TIL(Today I Learned)' 카테고리의 다른 글
7/12 (화) Spring MVC 테스팅 1️⃣ (0) | 2022.08.02 |
---|---|
7/21 (목) 인증 / 보안 기초 2️⃣ (0) | 2022.07.25 |
7/11 (월) Spring Framework에서의 트랜잭션 처리 (0) | 2022.07.17 |
7/8 (금) [Spring MVC] 트랜잭션(Transaction) (0) | 2022.07.16 |
7/7 (목) [Spring MVC] JPA 기반 데이터 액세스 계층 3️⃣ - Spring Data JPA (0) | 2022.07.16 |