인터넷을 하다 보면 회원가입 페이지를 마주치게 된다. 사이트마다 다르지만 아이디와 비밀번호는 공통적으로 물어본다. 아이디는 사용자를 식별하기 위해, 비밀번호는 해당 사용자가 정말 본인이 맞는지 확인하기 위해 사용된다. 최근에는 아이디 대신에 이메일을 물어보는게 추세이긴 하지만, 역할상에서는 차이가 없다. 아이디와 비밀번호 조합은 회원제 사이트의 초창기 부터 사용됐다. 별도의 장치(지문 판독기, 카드 리더기등)도 필요없고, 서버측에서 확인하는 작업또한 구현이 간편하다. 그러나 인증 시스템에 비밀번호를 사용하면 몇가지 단점을 안고가게 된다. 현 시대에는 이런 단점을 해소하기 위해 많은 보안적 장치와 기술이 들어왔다.

초창기 비밀번호 체계

아주 옛날, 회원제 사이트가 막 만들어졌을때는 비밀번호라는 개념이 없었다. 비밀번호 개념은 고대에서 부터 있었지만 (암구호도 일종의 비밀번호 개념이다!) 인터넷에 사용되지는 않았다. 특히 개념을 메일링 시스템까지 확장한다면 더더욱 그렇다. 애초에 인터넷 자체를 쓰는 사람이 적었다. 지금과 달리 대학교수나 연구진, 그외 관계자들만 인터넷에 접근 할 수 있었다. 믿을수 있는 사람들 끼리만 인터넷에 접근할 수 있었고, 굳이 그들이 타인을 사칭할 일 또한 없었다. 그 당시 웹을 이용한 서비스 또한 단순했기 때문에 굳이 “본인”인증이 필요한 순간도 없었다.

그러다가 인터넷이 많은 사람에게 퍼지기 시작하면서 몇가지 문제가 발생하기 시작한다. 인터넷이 여러 분야에 사용되면서 “정말 본인이 맞는지” 확인할 필요성이 생겼다. 기업 내부 시스템을 인터넷을 이용해서 만들었다고 하자. 비밀번호가 없으면 직원 이름만으로 사내 정보를 전부 조회할 수 있다. 게시판 등에서는 남의 이름을 사칭하여 악의적인 글을 쓸 수도 있다. 결국 인터넷이 확장되면서 비밀번호의 필요성이 늘어난 것이다.

초창기에는 비밀번호를 평문으로 보냈다. 암호화 없이 그냥 인터넷에 비밀번호를 전송했다. 서버측에서도 비밀번호를 그대로 저장했다. 비밀번호가 정말 “본인을 인증하는것” 그 이상도, 이하도 아녔기 때문이다. 해킹이라는 개념이 학술적으로만 있었기도 하고, 암호화를 하기 위한 여건또한 충분하지 않았다. 지금에 와서는 비밀번호를 이렇게 다루면 보안문제가 분명 발생할 것이다.

Hash와 SSL의 등장

네트워크에서는 크게 3가지 공격 포인트가 존재한다. 네트워크는 [클라이언트(PC)-네트워크-서버] 구조를 띄게 되는데, 공격 포인트 또한 클라이언트, 네트워크, 서버로 세개 존재한다. 어느 하나라도 뚫린다면 즉시 보안위협이 된다. 특히 최근에는 비밀번호만으로 물품 결제나 송금까지도 가능해졌기 때문에, 그 위험성은 더 높아졌다. 그 중에서도 서버측에서 뚫린다면 해당 서비스에 등록되어 있는 모든 사용자 정보가 누출될 수 있다.

보안위협을 막기 위해서 여러 장치가 시장에 도입됐다. 예전에는 ActiveX류 프로그램에서 클라이언트단 보안을 담당했다. 현재는 nProtect, Ahnlab Safe-Transaction등이 클라이언트단 보안을 담당한다. 네트워크상의 보안위협을 막기위한 장치로는 SSL(TLS)가 가장 대표적이다. 서버단의 보안위협은 대게 코드상의 오류나 보안을 고려치 않은 코딩에서 발생한다. 개발자들의 보안의식의 상승과 함께 기술적 조치로 (망, 또는 데이터 분리, 민감정보 해시화 및 암호화등) 풀어나가고 있다.

여기서 SSL과 Hash 암호화의 대중화가 보안 향상에 큰 도움이 됐다. 네트워크상에서 전송되는 데이터 자체는 전혀 암호화가 되지 않는다. 누구든 네트워크의 중간 지점을 감청할 수 있다. 그렇기 때문에 감청을 막을수 있는 수단이 필요하다. 여기서 사용되는게 SSL(TLS)이다. SSL을 이용하면 네트워크 사이에서 흘러다니는 데이터를 안전하게 보호할 수 있다. 인증서를 위조하여 적극적인 MITM을 시도할 수도 있고, SSL 말고 IPSec같은것도 있긴 하지만, 아직 널리 사용되진 않음으로 건너뛰자.

해시는 비밀번호를 한번 꼬아서 원래의 비밀번호를 알 수 없게 한다. 주로 서버단에서 비밀번호를 저장할 때 사용된다. 해시는 함수처럼 작동한다. 즉, 특정한 입력값을 특정 결과값으로 바꾸어준다. 그러면서 결과값을 가지고 입력값을 추측 못하도록 한다. (암호적 해시함수) 그러므로, 비밀번호를 해시화 하면 DB에 저장된 데이터 만으로는 원래 비밀번호를 추측할 수 없다.

더 나은 방법?

그렇지만 보안에 신경을 많이 쓰는 사람들은 이것만으로는 충분하지 않다고 생각했다. 그러면서 더 복잡한 방식을 고안했다. 그중 대표적인것이 클라이언트에서 비밀번호를 직접 해시화 해서 보내는 방법이다. 이러면 네트워크의 보안이 불충분 하더라도 원본 비밀번호 대신 해시화 된 비밀번호밖에 유출되지 않는다. 사실 서버에 저장된 것을 비교하는 부분에서는 다를것이 없다. salt를 이용해서 매번 다른 hash를 보내기 때문에 좀 더 안전하다는것이 다르다. (물론 salt가 유출되면 의미없다) 원본 비밀번호를 알기 어렵게 하는것이 중요하다. 그 외에도 많은 방법들이 있다.

그러나 언젠가 한번은 비밀번호를 서버로 전송해야 한다는것은 동일하다. 서버는 늘 비밀번호를 가지고 있어야 한다. 클라이언트는 최초에 비밀번호를 보내야 한다. 근본적으로 “회원시스템”에 비밀번호를 저장하지 않는 방법을 찾아야 했다. 비밀번호가 없다면 어떻게 사용자를 인증할 수 있을까? 바로 인증의 책임을 보다 안전한곳으로 미루면 된다. “굳이” 우리가 회원을 인증할 필요가 없다. oAuth(또는 OpenID)를 통해서 믿을수 있는 제3자에게 본인확인의 책임을 미루면 된다. 또는 이메일에 1회용 로그인 전용 코드를 보낼수도 있다.