‘풀리퀘’는 깃허브에서 타인의 코드에 리뷰를 요청하는 기능인 ‘풀 리퀘스트’의 줄임말입니다. 풀리퀘를 통해 코드는 더 발전하는데요. 알아두면 쓸모 있는 IT업계의 크고 작은 사건들을 변규홍 스켈터랩스 개발자가 격주로 ‘풀리퀘’ 드립니다.
▲ <그림 1></div> 영화 <레디 플레이어 원> 속 장면 갈무리. 소렌토의 비밀번호가 포스트잇에 잘 적혀 있다. 비밀번호를 모르는 사람(소렌토 본인 포함)도 이 포스트잇만 읽을 수 있으면 소렌토인 척 접속할 수 있다.
▲ <그림 1> 영화 <레디 플레이어 원> 속 장면 갈무리. 소렌토의 비밀번호가 포스트잇에 잘 적혀 있다. 비밀번호를 모르는 사람(소렌토 본인 포함)도 이 포스트잇만 읽을 수 있으면 소렌토인 척 접속할 수 있다.

스티븐 스필버그의 SF 영화 <레디 플레이어 원>에 등장하는 사람들은 하루의 대부분을 가상현실 세계인 ‘오아시스(OASIS)’에서 보낸다. 일종의 메타버스(Metaverse)다.[1] 오아시스에 접속할 땐 접속하려는 계정의 비밀번호를 알아야 한다. 비밀번호만 알면 인증(Authentication) 절차는 끝난다. 영화 속 대기업 경영진인 놀란 소렌토에겐 비밀번호를 항상 기억할 수 있는 특별한 비법(?)이 있다. 바로 사무실의 오아시스 접속 단말기 안쪽에 붙어 있는 메모지에 비밀번호를 적어 두는 것이다.[2]

물론 이렇게 종이에 적힌 순간 비밀번호는 더이상 ‘비밀’이 아니다. 출입문이나 컴퓨터 등의 전자기기, 게임 계정 등에 비밀번호라는 인증수단을 사용할 때의 기본적인 가정은, 권한이 없는 제3자는 비밀번호를 알 방법이 없으니 비밀번호를 맞춘 사람은 권한이 있는 것으로 간주하는 것이다. 그러므로 메모지에 비밀번호를 적는 행위는 이런 근본적인 가정을 망가뜨리는 셈이다. 실제로 2016년 4월경, 국내 정부기관 사무실 출입문과 컴퓨터 모니터에 비밀번호가 그대로 노출돼 있던 탓에 외부자가 손쉽게 내부로 침입한 사건이 발생해 사회에 충격을 준 바 있다.[3]

코로나19 감염병 대응을 위해 재택근무에 돌입하면서 사무실 바깥에서도 회사 내부 네트워크에 접속할 수 있는 VPN(Virtual Private Network)기술을 쓰는 경우가 점점 많아지고 있다. 그만큼 보안 위험도 가파르게 증가하는 추세다. 2021년 12월, 국가정보원은 언론을 통해 국내외 수만개 회사의 VPN 계정과 비밀번호가 무더기로 유출됐다는 소식을 전했다.[4] 유출된 ID, 비밀번호, VPN 서버주소 등을 조합하면 회사 내부 기밀정보 등에 접근할 수 있게 될 가능성이 커진다. 따라서 유출된 비밀번호는 유출 사실을 알게 된 즉시 변경해야 한다.[5]

이번 풀리퀘에서는 비밀번호 보안에 관해 개발자들이 놓치지 말아야 하는 주의사항을 살펴보려 한다.

fail2ban: 비밀번호 계속 틀리는 사람, 일단 막고 보자
국내 많은 은행의 현금 입출금 카드 비밀번호는 4자리 숫자로 구성된다.[6] 0000부터 9999까지, 각 자리마다 10가지 가능성이 있으니 경우의 수는 10의 4거듭제곱, 1만가지다. 그렇다면 남의 현금 입출금 카드를 가지고 ATM기를 찾아가 최대 1만 번만 시도하면 비밀번호를 맞춰 계좌에서 돈을 빼낼 수 있지 않을까.

결론부터 말하면 그런 일은 불가능하다. 비밀번호가 맞을 때까지 가능한 모든 경우의 수를 시도하며 비밀번호를 알아내는 공격을 브루트포스 공격(무차별 대입 공격·Brute-Force Attack) 이라고 한다. 횟수 제한이 없다면 은행 비밀번호는 브루트포스 공격 앞에서 금세 뚫릴 것이다. 이를 막기 위해선, 비밀번호 입력을 시도할 수 있는 횟수를 제한할 수밖에 없다.

이 때문에 보통 비밀번호를 3번 넘게 틀리면 은행에서 보안 위험 상황이 발생한 것으로 감지하고 현금 인출을 차단한다. 인간적인 실수는 2번까지만 허용하고, 그 이상 틀린 비밀번호를 입력하면 남의 계좌에서 돈을 훔치려는 사람이 아닐지 의심해 일단 막는다. 비밀번호가 헷갈리는 사람이야 횟수 제한 없이 시도하고 싶겠지만, 은행으로서는 일시적인 건망증과 도둑놈(?)의 행동을 분간할 길이 없는 탓이다.

요즘의 안드로이드나 아이폰 등 스마트폰, 윈도우 등 주요 운영체제(OS)에서도 비밀번호를 여러 차례 틀리면 일정 시간동안 비밀번호 입력을 차단하고, 기기를 쓰지 못하도록 하는 설계가 들어가 있다.[7] 리눅스 서버를 관리하는 개발자라면, 이와 비슷하게 ssh 원격 접속을 시도하면서 짧은 시간동안 비밀번호를 계속 틀리는 경우가 감지될 때 해당 IP로부터의 접속을 차단하는 fail2ban 같은 오픈소스 도구를 꼭 사용하는 편이 좋다.[8][9] 웹 서비스 등에 비밀번호 관련 설계를 직접 해야 한다면, 비밀번호를 여러 차례 틀렸을 때 적절한 차단이 이뤄지도록 하는 데 유의하자.

▲ (출처=픽사베이)
▲ (출처=픽사베이)
단방향 해시 함수: 비밀번호끼리 말고, 이를 가공한 결과물끼리 비교하기
돌아보면 2014년만 하더라도 ‘비밀번호 찾기’ 기능을 사용하면 서버에 저장된 비밀번호 원문을 알려주는 사이트들이 더러 있었다. 2022년 현재는 웹사이트에서 ‘비밀번호 찾기’ 기능을 제공하는 경우는 거의 없다. 메뉴 이름에는 흔적이 남아 있더라도 대부분 ‘비밀번호 초기화’, ‘비밀번호 재설정’ 기능으로 바뀌었다. 잊어버린 비밀번호를 알려주지 않는 데는, 그만한 이유가 있다.

비밀번호의 원문이 서버 데이터베이스(DB)에 저장돼 있는 상황은 앞서 <레디 플레이어 원> 등의 사례에서 살펴본 상황과 크게 다르지 않다. 서버 DB를 열람할 수 있는 사람에게는 비밀번호가 더 이상 ‘비밀’이 아니다. 비밀번호를 ‘복호화’ 가능하게 ‘암호화’해서 저장해도 마찬가지다. 서버 DB를 열람할 수 있는 사람이라면 비밀번호 복호화 방법도 알 수 있을 테니까. DB에 접근할 수 있다면 비밀번호 처리와 관련된 소스코드나 프로그램에도 접근할 수 있을 가능성이 크다. 서버 관리자, 혹은 서버 해킹에 성공한 악의적인 공격자에게 비밀번호가 유출되는 상황을 원천 봉쇄하기 위해서라도, 비밀번호는 서버에 저장될 때 항상 복호화할 수 없는 형태로 저장돼야 한다. 비밀번호 인증방식 또한 비밀번호 원본과 대조하는 방식이 아니어야 한다.

한국인터넷진흥원이 2018년 발간한 <패스워드 선택 및 이용 안내서>에서는 이를 위해 ‘일방향 해시 함수’ 혹은 ‘단방향 해시 함수’를 소개한다. [10] ‘해시 함수’는 보통 입력된 내용을 고정된 길이의 문자열로 바꿔주는 함수를 말한다.

예를 들어, md5 해시 함수를 사용해 ‘helloworld’의 해시값을 구하면 ‘fc5e038d38a57032085441e7fe7010b0’라는 문자열이 나온다.[11] 비밀번호가 ‘helloworld’ 라면 서버에는 ‘fc5e038d38a57032085441e7fe7010b0’만 서버 DB에 저장해 두고, 나중에 비밀번호 인증 요청이 발생하면 그때 입력된 비밀번호에 동일한 해시 함수를 적용한 결과물과 서버 DB에 저장된 내용을 비교하는 방식을 택하면 된다. 자, 그럼 다음 질문으로 넘어갈 차례다. md5 함수로 충분한 걸까.

md5 해시는, 쓰지 말자
세상에는 다양한 해시 함수가 있는데, 아직까지도 비밀번호를 저장할 때 md5 해시 함수를 사용하는 사례가 상당히 많다. 2020년에도 한국의 한 회사가 md5 해시 함수를 써서 비밀번호를 저장했다는 기사가 나온 적이 있다.[12] 최근 IEEE S&P(Symposium on Security and Privacy)에 발표된 논문 에서도 코딩 실력을 갖춘 인공지능(AI)이 깃허브(Github) 등의 오픈소스 저장소를 통해 배운 내용을 토대로 비밀번호 저장 방식으로 md5 해시 함수를 사용하는 모습이 발견됐다고 보고했을 정도다.[13] [14]

그러나 위에 언급한 논문에서도 지적하는 바와 같이, 이는 정말 위험한 일이다. 서버 DB를 확보한 해커라면 브루트포스 공격으로 md5 해시의 원본을 알아내는 시도를 해볼 수 있다. 벌써 10년도 전인 2011년, 고려대학교 김승주 교수 연구팀은 <SBS뉴스>를 통해 브루트포스 공격을 사용해 md5 해시 함수 결과물인 ‘9c4be391980adfe67b90bd9c7848f25e’가 6자리 비밀번호 ‘sbs911’이란 것을 당시 컴퓨터 기준으로 3초면 알아낼 수 있다는 사실을 소개했다. [15] 2013년에 이미 한국인터넷진흥원이 정리한 <암호화된(해시) 비밀번호도 더 이상 안전하지 않다>[16]에서도 충격적인 사례들이 대거 보고된 바 있다.

다음 표는 이번 풀리퀘를 쓰면서 오픈 소스 라이브러리인 hashcat에게 md5 해시 함수 결과물을 주고 원본을 맞추는 데 걸린 시간을 정리한 내용이다.[17] 컴퓨터 1대만으로도 이렇게 금방 원본을 알아낼 수 있는데, 수만대의 좀비 PC를 확보한 해커에게 md5 해시 함수 결과물이 유출된다면 어떻게 될까. 2022년엔 비밀번호를 저장할 훨씬 좋은 방법이 무수히 많이 제시되고 있다. [18] md5는, 쓰지 말자.

특수문자를 섞어쓰는 것보다 긴 비번이 낫다면
그렇다면 안전한 비밀번호는 어떻게 만들 수 있을까. 비밀번호에 글자 수 제한이 있다면 아무래도 각 글자의 경우의 수가 다양할수록 좀더 맞추기 어려워질 것이다. 알파벳 소문자로만 8글자로 구성되는 비밀번호는 aaaaaaaa부터 zzzzzzzz까지 208827064576가지 경우의 수(26의 8거듭제곱), 즉 2000억가지 조합 정도가 가능하겠다. 소문자와 숫자를 조합한다면 36의 8거듭제곱인 2821109907456가지 경우의 수, 대소문자와 숫자라면 62의 8거듭제곱인 218340105584896가지 가능성이 있다. 33가지 특수문자를 더하면 각 자리마다 95가지 경우의 수가 가능하니, 95의 8거듭제곱, 6634204312890625가지 가능성으로 늘어난다. 같은 길이라면 비밀번호를 구성하는 문자의 종류가 다양할수록 좋다. 앞에서 hashcat 도구로 md5 해시 함수에 브루트포스 공격을 하는 데 걸리는 시간이 늘어나는 모습에서 충분히 느낄 수 있을 것이다.

여기까지만 놓고 보면 비밀번호를 알파벳 소문자·대문자, 숫자, 특수문자를 골고루 섞어서 만들도록 하는 게 합리적인 것처럼 보인다. 하지만 이쯤에서 본질적인 질문을 던져보자. 왜 비밀번호의 길이가 제한되어야 할까? ‘wewritepullrequesttogether’처럼 알파벳 소문자로만 길게 비밀번호를 쓴다면? 26글자의 알파벳 소문자 26글자로 구성되는 비밀번호는 26의 26 거듭제곱인 6156119580207157310796674288400203776가지 경우의 수가 가능해진다. md5 해시 함수를 쓴 경우에도 PC 1대에 hashcat을 써서 이를 맞추는 데는 390경 년이 걸린다. 특수문자를 모두 섞은 경우의 18자리 비밀번호보다 더 맞추기 어렵다.[19] 이를 단적으로 소개하는 xkcd 에피소드를 아직 보지 않았다면 일독을 권한다.[20] 그러니 사실은 비밀번호에 특수문자를 섞어 쓰는 것보다 길이 자체가 길어지는 게 낫다.

그 비밀번호, 안전한 이유보다 안전하지 않은 이유가 더 많다
여기까지 비밀번호를 어딘가에 적어 두지 말아야 하는 이유부터 시작해서 비밀번호 인증을 사용할 때 횟수 제한이 필요한 이유와 함께 md5 해시 함수를 비밀번호 저장 용도로 쓰지 말아야 하는 이유를 살펴봤다. 사실 아직도 비밀번호의 길이를 굉장히 짧은 수로 제한하는 곳이 많다. 짧고 외우기 어려운, 복잡해 보이기만 하는 비밀번호보다 길지만 직관적이고 외우기 쉬운 비밀번호가 낫다는 사실을 개발자라면 유념해야 할 것이다. 하지만 어디에나 함정은 있다. 다음 풀리퀘에서는 그런 비밀번호조차 안전하지만은 않은 이유, 그리고 비밀번호를 둘러싼 몇 가지 딜레마도 함께 살펴보자.[기고|변규홍 스켈터랩스 개발자]

▲ 기고|변규홍 스켈터랩스 개발자
▲ 기고|변규홍 스켈터랩스 개발자

※각주

[1]: https://movie.daum.net/moviedb/main?movieId=96030
[2]: https://scifi.stackexchange.com/questions/185671/what-was-nolan-sorrento-s-password
[3]: https://www.donga.com/news/article/all/20160408/77466084/1
[4]: https://news.kbs.co.kr/news/view.do?ncd=5347423
[5]: 사실 VPN처럼 중요한 시스템에는 비밀번호에만 의존하지 말고 MFA(Multi-Factor Authentiation; 다중 인증)같은 방법을 도입하는 것이 좋다. 다음 풀리퀘에서도 이에 관해 좀더 살펴보자.
[6]: https://www.korea.kr/news/actuallyView.do?newsId=148777051&call_from=naver_news
[7]: 이런 방법도 기기 자체를 분해해 메모리 반도체 칩의 내용을 복제하는 등의 방법으로 우회할 수 있다는 주장이 있다. https://zdnet.co.kr/view/?no=20160401163007
[8]: https://github.com/fail2ban/fail2ban [9]: https://www.fail2ban.org/
[10]: https://www.privacy.go.kr/pds/passwd_encrypt.pdf
[11]: python 의 hashlib 모듈을 사용해 hashlib.md5(b’helloworld’).hexdigest()를 한 결과물이다.
[12]: http://m.boannews.com/html/detail.html?idx=89382&tab_type=1
[13]: https://www.computer.org/csdl/proceedings-article/sp/2022/131600a980/1A4Q3Mv66CQ
[14]: https://arxiv.org/abs/2108.09293
[15]: https://news.sbs.co.kr/news/endPage.do?news_id=N1000960683&plink=OLDURL
[16]: https://www.krcert.or.kr/data/trendView.do?bulletin_writing_sequence=2304
[17]: https://github.com/hashcat/hashcat
[18]: bcrypt, scrypt, pbkdf2 라는 말이 생소하다면 한번 찾아보고, KISA의 “암호이용활성화” 홈페이지를 한번 정독하자. https://seed.kisa.or.kr/kisa/index.do
[19]: https://pages.nist.gov/800-63-3/sp800-63b.html를 읽어보라는 조언을 많이 들을 것이다. 이에 대한 언론 기사부터 읽어봐도 좋다. https://cm.asiae.co.kr/article/2020112800064913682
[20]: https://xkcd.com/936/

저작권자 © 블로터 무단전재 및 재배포 금지