저희가 일상에서 사용하는 인터넷 서비스는, 일부는 공개되어 있고 일부는 비공개로 남아있습니다. 많은 서비스들이 이 비공개되어 있는 부분의 사용허가에 대해서 로그인을 요구하게 됩니다. 이 로그인의 과정을 개발하는데 있어서 흔히 Auth라는 용어를 사용하게 됩니다.
로그인
로그인이라는 말의 의미는 위키피디아 기준으로,
•
어느 한 개인이 자기 자신을 증명함으로서,
•
특정 컴퓨터 시스템에 접근하는 행위
라는 의미를 가지고 있습니다.
저희는 개발 공부를 하면서, 로그인을 통해 필요한 자원에 접근한 경험이 있습니다. 다름아닌 Database의 사용 과정에서죠. 처음 데이터베이스를 구성하면서 User를 추가하고, Schema를 추가하며, 그 User가 Schema를 사용할 수 있도록 설정하였습니다.
Authorization & Authentication
Auth라는 말로 잘라서 이야기하지만, Auth는 두가지 의미를 가지고 있습니다. 하나는 Authorization, 다른 하나는 Authentication 입니다.
•
Authentication: 사용자가 누구인지를 증명하는 과정
•
Authorization: 사용자의 권리를 검증하는 과정
흔히 기획단계에서 말하는 로그인 과정은 Authentication에 해당하는 과정입니다. Authentication은 단순히 로그인 화면 및 과정에 그치지 않고, 원격 API 호출 과정에서 필요한 사용자 검증 등에서도 요구하게 되는 내용입니다. 저희가 흔히 하는 로그인 과정에서 사용자의 아이디 비밀번호가 외부에서 쉽게 노출되지 않도록 하기 위한 과정을 비롯하여, 로그인 과정을 거치지 않은 채로 요청하는 사용자가 누군지를 확인하는 방법론에 대한 내용입니다.
Authorization은 블로그, SNS, 클라우드 등 여러 서비스에서 사용자의 기능을 상황에 따라 구별하기 위한 과정입니다. 언뜻 간단하게 생각될 수 있습니다만, 평범한 서비스에 사용자 권한에 따른 기능 변화는 서비스 구현의 난이도를 올리는 가장 흔한 이유가 됩니다. 특히 블로그, 평범한 SNS 등에는 가능, 불가능 여부만 구분해주면 되는 반면, 카페 서비스 같은 게시판을 만들고, 추가로 해당 게시판에 대한 권한의 관리가 서비스 진행 중에 이뤄져야 합니다.
웹서비스의 일반적인 로그인 과정
HTTPS
Auth와는 별개로 HTTPS, 정확히는 TLS에 대해서 알아봅시다. 저희가 일반적으로 사용하는 HTTP는, 요청과 응답에 대한 암호화가 진행되지 않습니다. 이는 데이터의 전송과정에서, 제3자가 얼마든지 그 내용을 다시 확인할 수 있다는 의미입니다. 그래서 상용 서비스 단계에서는 HTTP가 아닌 HTTPS를 사용하게 됩니다.
암호화
인터넷 상의 다른 컴퓨터로 데이터를 보내면서, 그 내용이 쉽게 공개되지 않도록 내용을 특정한 규칙에 따라 바꾸는 과정을 암호화라고 합니다. 이때, 암호화 하기 전의 데이터를 평문, 암호화를 거친 데이터를 암호문이라 부르고, 암호화를 거친 암호문을 다시 평문으로 고치는 과정을 복호화라고 합니다. 암호화와 복호화를 진행하기 위해서는, 암호를 만들고 다시 해석하기 위한 키가 필요하며, 이 키를 어떻게 사용하는지에 따라 두가지로 나눌 수 있습니다.
•
대칭키 암호화: 서로 공개하지 않는 동일한 키를 공유하고, 해당 키를 사용해서 암호화와 복호화 과정을 거칩니다.
•
공개키 암호화: 비대칭키 암호화라고도 하는데, 어디에든 공개된 공개키를 사용해 암호화를 진행하고, 공개되지 않는 수신자의 비밀키를 사용하여 복호화를 진행합니다.
일반적인 상황에서, 대칭키 암호화의 경우 암호화 / 복호화 과정이 빠르나, 상대적으로 보안이 취약한 단점이 있으며, 공개키 암호화의 경우 상대적으로 보안이 뛰어나지만, 더 느리다는 단점을 가지게 됩니다. TLS의 경우는 이 두가지 방식의 암호화를 동시에 사용하는 방법입니다.
기본적인 과정은 위와 같습니다. 핵심적인 부분은, 대칭키 암호화를 하기 위한 공유되어야 되는 비밀키를, 비대칭키 암호화를 통해 공유한다는 부분입니다.
1.
클라이언트가 서버에 최초로 요청을 보낼때, 안전한 연결에 대한 요청과 함깨 자신이 사용할 수 있는 암호화 방식들을 서버에 보내주게 됩니다.
2.
서버는 클라이언트가 전달해준 방식들 중 자신이 사용할 수 있는 방식을 선택하고, 그 정보를 자신의 인증서와 함깨 전달합니다.
3.
클라이언트는 서버가 전송해준 인증서를 확인합니다. 이 인증서는 서버의 신분 증명과 함깨 서버의 공개키가 포함되어 있습니다.
•
여기서 서버의 공개키를 사용해 암호화를 진행한 암호문은, 서버만 알고있는 개인키를 사용해야만 그 값을 확인할 수 있습니다.
4.
클라이언트가 서버의 공개키를 사용해 임의의 값을 암호화하여 서버로 전달합니다.
•
이 중간의 통신 내용을 읽히더라도, 서버의 개인키가 없으면 임의의 값을 확인할 수 없습니다.
5.
서버가 전달받은 암호문을 자신의 개인키로 복호화하여, 클라이언트가 생성한 임의의 값을 확인합니다.
•
이제 이 임의의 값은 대칭키 암호화 방식의 키로서 활용합니다.
6.
서버가 클라이언트에게, 대칭키로 암호화된 응답을 보내면 클라이언트가 같은 대칭키로 복호화를 합니다.
7.
클라이언트가 서버에 요청을 보낼때, 대칭키로 요청을 보냅니다.
이와 같은 과정을 통해 이후의 통신을 중간에 가로 챈다 하더라도, 그 내용 자체의 확인은 (거의) 불가능해집니다. 그렇기 때문에 현대의 웹 서비스는 HTTPS는 필수적으로 요구하게 됩니다.