꾸준히
암호학1, 쿠키, 세션, 토큰, JWT 본문
암호학(Cryptography)
암호학(Cryptography)은 비밀이라는 뜻의 "crypto"와 방법이라는 뜻의 "graphy" 결합으로 비밀을 다루는 방법이다. 암호의 3가지 특성에는 기밀성, 무결성, 인증이 있다.
- 기밀성(Confidentiality) : 암호화된 내용이 무엇인지 알 수 없어야 한다.
- 무결성(Integrity) : 내용이 원본과 같다는 것을 확신할 수 있어야 한다.
- 인증(Authentication) : 권한이 있는 사람만 접근할 수 있어야 한다.
암호화는 평문(plain text)을 암호 알고리즘(cryptography algorithm)을 통해 암호문(cipher text)으로 변환하는 과정을 거친다. 평문을 암호문으로 만드는 과정을 암호화(encrption)라고 하며 그 반대 과정을 복호화(decryption)라고 한다. 과거에는 암호 알고리즘을 공개하지 않음으로써 암호화를 달성했지만 현대 암호화는 암호 알고리즘을 공개하여 검증받는 과정을 거친다. 대신 암호를 만들고 풀 때 비밀 정보를 적는다. 이 비밀 정보를 키(key)라 칭한다.
암호화 방식
- 양방향 암호화 방식 : 암호화, 복호화를 모두 할 수 있는 암호법으로 기밀성에 초점을 맞춘 방식이다.
- 단방향 암호화 방식 : 암호화는 가능하나 복호화는 불가능한 암호법으로 무결성에 초점을 맞춘 방식이다. (ex. md5, sha)
양방향 암호화 방식
대칭키 방식
암호화, 복호화에 모두 같은 키를 사용하는 방식으로 AES, Twofish가 대표적이다. 대칭키 방식의 치명적 단점은 허가된 사람에게만 정보를 전달해야 하는 상황에서 기밀성이 보장되지 않는다는 것이다. 암호문과 함께 암호문을 복호화할 키도 함께 전달해야 하는데, 이때 허가되지 않은 자가 키와 암호문을 탈취했다고 가정하자. 대칭키 방식은 암호화와 복호화에 쓰이는 키가 동일하기 때문에 탈취한 키를 통해 암호문을 복호화할 수 있다. 즉, 기밀성이 보장되지 않는다.
비대칭키 방식(공개키 방식)
비대칭키 방식은 공개키 방식으로도 불리며 암호화, 복호화 과정에서 각각 다른 키를 사용하는 방식으로 RSA가 대표적이다. 이때 두 키를 공개키(public key), 비공개키(private key)라 부르며, 이 두 키를 key pair라고 부르기도 한다. 이름에서부터 알 수 있듯 공개키는 외부에 공개돼도 무관하며 비공개키는 반드시 공개되서는 안 된다. 공개키로 평문을 암호화했다면 반드시 비공개키로 복호화가 가능하다. 반대로 비공개키로 암호화했다면 반드시 공개키로만 복호화가 가능하다.
앞서 본 대칭키 방식의 취약점을 비대칭키 방식에서 보완할 수 있다. A는 자신의 공개키를 외부에 공개하고 B는 A에게 전달하고자 하는 메시지를 A의 공개키를 통해 암호문으로 암호화하고 전달한다. 이 과정에서 A의 공개키와 암호문이 허가되지 않은 자가 탈취했다 하더라도 공개키를 사용하여 암호문을 복호화할 수 없다. 즉, 기밀성이 보장된다.
비대칭키 방식은 전자 서명에도 사용된다.
단방향 암호화 방식
단방향 암호화는 해시(Hash)라고도 불리며 사전적 의미로는 "다지다"가 있다. 음식을 다지면 원래 상태로 돌아갈 수 없듯이 어떤 데이터를 해시하면 그 데이터를 원래 상태로 되돌릴 수 없다. 어떤 데이터가 원본으로부터 훼손되었거나 조작되었는지 확인하는 무결성을 위해 해시를 사용한다.
암호의 보안성
암호의 보안을 높이기 위해서는 키 값을 길게 하거나 HASH 값이 긴 알고리즘을 사용해야 한다. 하지만 키 값이 길어지면 암호화, 복호화에 더 많은 컴퓨터 자원을 사용해야 하기 때문에 적절한 암호화 방법을 사용해야 한다. 국가에서는 그 시대에 어울리는 적당한 암호화 방법을 권고하고 있다.
https://www.kisa.or.kr/2060305/form?postSeq=5&lang_type=KO#fnPostAttachDownload
KISA 한국인터넷진흥원
www.kisa.or.kr
비밀번호의 암호화
사용자의 비밀번호를 어떤 방식으로 데이터베이스에 저장해야 할까? 비밀번호 문자열 자체를 저장한다면 데이터베이스에 접근 가능한 어드민, 직원이 다 확인할 수 있기 때문에 보안 문제가 발생할 수 있다. 이를 해결하기 위해 비밀번호를 암호화하는 방식도 있다. 사용자는 회사에서 제공한 키를 사용하여 암호를 우선 해제한 후 비밀번호가 맞으면 로그인하고 다시 암호화하는 방식이다. 하지만 이는 키를 잃어버리거나 키를 도난당할 시 문제가 발생한다. 다른 방법은 해시 함수를 사용하는 것이다. 비밀번호를 해시 함수의 결괏값으로 저장하는 것이다.
해시 함수는 동일한 입력값에 대해 동일한 출력값을 가지고 있으며 입력값이 조금만 바뀌더라도 상당히 다른 값을 출력한다. 또한, 해시 함수는 항상 같은 방향으로만 작동한다. 즉, 입력값 a에 대한 출력값이 b라고 해서 b를 입력했을 때 a가 출력되지 않는다.
레인보우 테이블(Rainbow table)을 이용한 해킹은 앞서 본 해시 함수의 특징을 이용한다. 레인보우 테이블이란 해시값을 입력값과 연결해놓은 테이블이다. 데이터베이스에 저장된 해시값을 레인보우 테이블에서 찾아 입력값인 비밀번호를 알아내는 방식으로 해킹한다.
이러한 해킹을 막기 위해 솔트(Salt)를 활용한다. 솔트란 추가로 입력되는 매우 작은 랜덤한 데이터이다. 사용자가 계정을 만들 때 비밀번호를 솔트와 함께 해시하여 레인보우 테이블에 매칭되는 값이 없게 한다.
쿠키(Cookie)
쿠키는 브라우저에 저장된다. 사이트에 방문하면 브라우저는 서버에 요청하고 서버는 이에 응답하는데 이 응답에는 브라우저에 저장하고자 하는 쿠키가 있을 수 있다. 브라우저가 쿠키를 저장한 후에 해당 사이트에 방문할 때마다 해당 쿠키도 요청과 함께 보내진다. 쿠키는 도메인에 제한되며 유효기간이 있다는 특징이 있다. 쿠키에는 인증 외 언어설정 등 클라이언트의 편의를 위한 정보 또한 저장된다.
세션(Session)
어떤 사이트에 로그인하면 유저명과 비밀번호는 서버에 보내진다. 비밀번호가 맞다면 서버는 세션DB에 해당 유저를 생성한다. 해당 세션에는 별도의 ID가 있으며 이는 쿠키를 통해 브라우저로 돌아오고 저장된다. 따라서 같은 웹사이트의 다른 페이지로 이동하면 브라우저는 세션 ID를 가지고 있는 쿠키를 서버에 보낸다. 서버는 세션 ID와 함께 오는 쿠키를 확인한다. 해당 세션 ID를 가지고 있으면 세션 DB를 확인하고 해당 ID는 어떤 유저의 것인지 알게 된다. 이런 방식으로 서버는 유저를 확인하게 된다. 유저가 가지고 있는 것은 세션 ID 뿐이며 중요한 유지 정보는 모두 서버에 있다.
토큰(Token)
쿠키는 브라우저에만 있기 때문에 쿠키를 사용해 안드로이드나 iOS 앱을 만들 수 없다. 이 경우에 토큰을 사용한다. 서버에 토큰을 보냄으로써 서버는 세션 DB에서 해당 토큰과 일치하는 유저를 찾는다.
JWT
DB에는 현재 로그인한 유저들의 모든 세션 ID를 저장해야 한다. 요청이 들어올 때마다 서버는 쿠키를 받아 세션 ID를 보고 세션 ID와 일치하는 유저를 확인해야 한다. 요청이 들어올 때마다 DB를 찾아야하기 때문에 유저가 늘어남에 따라 DB 리소스가 더 많이 필요하다. 이런 맥락에서 JWT가 탄생하게 된다. JWT는 토큰 형식으로 유저 인증을 처리하기 위해 세션 DB를 가질 필요가 없다. 또한, 서버는 유저를 인증하기 위해 많은 일을 하지 않아도 된다.
JWT에서 서버는 유저를 인증하는 데 필요한 정보를 토큰에 저장한 후 해당 토큰을 우리에게 준다. 페이지를 요청하면 서버는 해당 토큰이 유효한지만 검증하면 된다.
JWT는 암호화되지 않았기 때문에 누구나 열어 해당 컨텐츠를 볼 수 있다. 비밀정보를 JWT 안에 두면 보안의 문제가 생길 수 있다는 단점이 있다. 또한 JWT는 생성된 토큰을 추적하지 않기 때문에 DB를 따로 살 필요가 없다. 하지만 이는 강제 로그아웃 등의 기능을 할 수 없다는 단점도 있다.
'Ping!' 카테고리의 다른 글
MySQL, PHP를 이용한 간단한 게시판 구현 (1) | 2023.03.14 |
---|---|
ARP 스푸핑 실습 (1) | 2023.03.02 |
VPN (1) | 2023.02.23 |
SSL (0) | 2023.02.16 |
정보보안과 해킹 기초, 네트워크 기본 (1) | 2023.02.02 |