보안

저장된 비밀번호를 보호하는 최선의 방법, 해싱의 정의와 작동 방식

Lucian Constantin | CSO 2021.01.18
해싱(Hashing)은 다양한 유형의 입력 값의 진본성(Authenticity)과 무결성(Integrity)을 검증하기 위해 사용할 수 있는 암호 기법 프로세스다. 

데이터베이스에 평문 비밀번호를 저장하지 않기 위해 인증 시스템에서 널리 사용되고 있지만 파일, 문서, 기타 유형의 데이터를 검증하는 데에도 사용되고 있다. 해싱 함수를 잘못 사용하면 심각한 데이터 유출로 이어질 수 있지만, 처음부터 해싱을 사용하지 않아 민감한 데이터를 보호하지 않는 것이 더 좋지 않다. 

 

ⓒ Getty Images Bank


단방향 암호 기법 해싱과 양방향 암호화 비교 

해싱은 단방향 암호 기법 함수인 반면, 암호화(Encryption)는 양방향으로 작동하도록 고안되었다. 암호화 알고리즘은 입력 값과 비밀 키를 가져다 암호문(ciphertext)이라는 무작위처럼 보이는 출력값을 생성한다. 이 작업은 가역적이다. 비밀 키를 알거나 가진 사람이 암호문을 복호화해 원본 입력값을 판독할 수 있다.

해싱 함수는 비 가역적이다. 해싱 함수의 출력값은 해시값, 다이제스트(Digest) 또는 해시(Hash)라 불리는 고정된 길이의 문자열이다. 본래의 값으로 변환할 수 없기 때문에 반드시 비밀로 유지할 필요가 없다. 

하지만 해싱 함수의 한 가지 중요한 함수는 해시 되었을 때 고유한 입력값이 항상 같은 해시값으로 귀결되어야 한다는 점이다. 2개의 입력값이 같은 해시값을 가질 수 있다면 이것을 충돌(collision)이라고 부르며 컴퓨터를 사용해 충돌 등을 얼마나 쉽게 찾을 수 있는지에 따라 보안 관점에서 해시 함수가 깨진 것으로 간주될 수 있다.

해싱은 데이터베이스에 비밀번호를 저장할 때 항상 암호화보다 더 많이 사용된다. 그 이유는 해킹 발생 시 공격자가 평문 텍스트에 접근할 수 없고 웹사이트가 사용자의 평문 비밀번호를 알 이유가 전혀 없기 때문이다. 

여러 기업에서 ‘우리의 직원들은 절대로 비밀번호를 묻지 않습니다’라는 공지를 받은 적이 있다면 그것이 바로 그 이유다. 비밀번호를 갖고 있을 필요가 없으며, 비밀번호에 대한 비 가역적인 암호 기법 표현, 즉 해시값이 있는 것이다.

즉, 데이터 유출을 당한 기업은 공개 석상에서 ‘암호화’라는 용어를 오용하고 고객에게 비밀번호가 암호화되어 있기 때문에 안전하다고 말하는 경우가 많다. 그것은 아마도 일반 대중이 해싱의 의미에 익숙하지 않기 때문에 PR 부서가 혼란을 피하고 싶기 때문일 것이다. 

이로 인해 외부 관찰자가 유출과 관련된 위험을 평가하기 어렵다. 왜냐하면 비밀번호가 정말 암호화되었다면 해시 처리되었을 때보다 위험성이 더 높기 때문이다. 그래서 다음과 같이 질문해야 한다. 암호화 키도 해킹됐는가? 비밀번호에 해싱 대신에 암호화를 사용하는 경우도 있다.

2013년, 어도비(Adobe)는 보안 사고를 겪었고 이로 인해 암호화된 비밀번호를 포함해 수백만 개의 계정 정보를 도난당했다. 어도비는 대부분의 시스템이 해싱을 사용하도록 업데이트했지만 유출된 서버는 해당 기업이 폐기하려던 백업 서버였고, 저장된 비밀번호는 ECB(Electric CodeBook) 모드의 3중 대칭키 암호(Triple Data Encryption Standard, Triple DES)로 암호화되어 있었다. 

공격자들은 복호화 키를 확보하지 못했지만 ECB 모드에서 이 암호(cipher)를 사용하면 정보가 유출되어 무차별 대입(Brute-force) 공격을 통해 상당 수의 비밀번호를 복구할 수 있다.

OWASP(Open Web Application Security Project)는 비밀번호 보관 권고사항에서 “암호화는 원본 비밀번호를 확보할 수 있어야 하는 특수한 사례에서만 사용해야 한다. 일부 사례에서는 필요한 경우가 있다. 애플리케이션이 비밀번호를 사용해 SSO(Single Sign On)를 지원하지 않는 외부 레거시 시스템에서 인증해야 하거나, 비밀번호의 개별적인 문자를 검색해야 하는 경우가 그렇다. 비밀번호 복호화 능력은 심각한 보안 위험을 의미하기 때문에 전체적인 위험을 평가해야 한다. 가능하면 대체 아키텍처를 사용해 비밀번호를 암호화된 형식으로 저장할 필요를 없애야 한다”라고 밝혔다.


해싱을 인증에 사용하는 방법

인증(Authentication) 시스템에서 사용자가 새 계정을 생성하고 선택한 비밀번호를 입력할 때 애플리케이션 코드가 해당 비밀번호를 해싱 함수를 통해 전달하고 결과를 데이터베이스에 저장한다. 

사용자가 추후에 인증하고 싶은 경우, 이 프로세스가 반복되고 결과를 데이터베이스의 값과 비교한다. 일치하는 경우에만 사용자에게 올바른 비밀번호가 제공된다.

사용자가 비밀번호를 잊어버린 경우에는 비밀번호 복구 프로세스에 신원 확인이 수반되며, 일반적으로 이메일을 통해 전송되는 고유한 비밀번호 재설정 링크를 클릭해 계정 생성 시 사용된 이메일의 소유권을 입증한다. 사용자가 새 비밀번호를 설정해 데이터베이스에 새 비밀번호 해시를 설정할 수 있도록 허용한다. 비밀번호 복구 프로세스를 통해 기존의 비밀번호가 이메일을 통해 사용자에게 전송되거나 브라우저상에서 표시되는 경우에는 안전하지 못하며 최선의 보안 사례를 준수하지 않은 것이다.

즉, 해싱을 사용하더라도 개발자는 안전하지 않으며 무차별 대입 공격에 취약한 것으로 알려진 해싱 함수를 사용함으로써 구현 오류를 범할 수 있다. 이런 해킹 유형은 과거에 많이 사용되었지만 더 이상 사용하지 않는 MD5 및 SHA-1에서 많이 찾아볼 수 있다.

1991년에 개발된 MD5는 오랫동안 그리고 암호 분석가들이 이론상 안전하지 않다는 것을 입증한 후에도 오랫동안 사실상의 해싱 함수로 사용됐다. 안타깝게도 MD5는 지금도 오래된 애플리케이션, 또는 보안을 이해하지 못하는 개발자들이 널리 사용하고 있다. 

최초의 부분적 충돌 공격은 1996년에 이론이 정립되었고 전체적 충돌은 2004년에 시연됐다. 현재 MD5 충돌은 일반 가정용 컴퓨터에서 몇 초 안에 발견할 수 있으며 알고리즘이 무차별 대입 공격에 매우 취약하다.

SHA-1(Secure Hash Algorithm-1)은 NSA가 1995년에 개발했으며 권장 NIST 표준이었다. 이 함수는 2005년 이후로 클라우드 컴퓨팅 성능에 접근할 수 있는 자원이 풍부한 공격자에게는 안전하지 못한 것으로 알려져 있다. 

2017년, 네덜란드의 CWI(Centrum Wiskunde and Informatica), 싱가포르의 NTU(Nanyang Technological University)의 연구원들과 구글과 협력한 프랑스 국립 정보통신기술연구소(INRIA)는 SHA-1 서명을 가진 2개의 PDF 파일을 생성해 SHA-1에 대한 실질적인 충돌을 입증했다. SHA-1은 TLS 인증서 등에 밀려났지만 오래된 장치와 시스템에서는 코드 저장소, 소프트웨어 업데이트 등의 파일 서명 검증을 포함해 다양한 목적으로 여전히 널리 사용되고 있다.

비밀번호 해싱과 보관의 경우, 최근 IETF(Internet Engineering Task Force) 초안에서 아르곤2(Argon2, 2015년 비밀번호 해싱 대회 우승작), 비크립트(Bcrypt), S크립트(Scrypt), PBKDF2를 사용하도록 권고했다. 

하지만 사용되는 알고리즘보다 해싱이 더 중요하다. 예를 들어, 최소 8글자의 비밀번호는 사전 공격(dictionary attacks, 다른 데이터 유출에서 확보한 보편적인 비밀번호 목록)에 의존하는 무차별 대입 공격을 훨씬 어렵게 만들기 때문에 중요하다.

각 해시 함수를 구현해 각 비밀번호에 해싱 알고리즘의 다수 반복 또는 패스(Pass)를 수행한다. 또한 워크팩터(Work Factor)라는 것이 있는데, 목표는 무차별 대입 방법을 사용해 결과를 해킹하기 위해 더 많은 컴퓨팅 자원을 사용하도록 하는 것이다. 워크팩터가 높아지면 보안성이 증가하지만 알고리즘이 여러 번 실행되기 때문에 각 해싱 연산의 컴퓨팅 자원 사용량이 늘어나고 느려진다.

OWASP는 권고사항에서 “이상적인 워크팩터에 대한 황금률은 없지만 서버의 성능과 애플리케이션의 사용자 수에 따라 달라진다. 최적의 워크팩터를 판단하려면 애플리케이션이 사용하는 특정 서버로 테스트해야 한다. 일반적으로 해시 계산에는 1초 미만이 소요되지만 트래픽이 높은 사이트에서는 이것보다 훨씬 낮아야 한다”라고 밝혔다.


비밀번호 해킹이 더 어려워지는 솔트와 페퍼의 이해

또 다른 안전한 비밀번호 보관 모범 사례는 각 비밀번호를 무작위로 생성된 ‘솔트(Salt)’라는 문자열과 조합한 후 결과를 해시하는 것이다. 그리고 모든 사용자와 비밀번호에 고유해야 하는 솔트를 해시와 함께 저장한다.

솔트 비밀번호는 특정 유형의 공격이 훨씬 힘들어지거나 불가능하게 만든다. 예를 들어, 공격자는 많은 수의 비밀번호 조합에 대해 해시를 사전에 연산한 후 레인보우 테이블(rainbow table)이라는 데이터베이스에 저장한다. 나중에 유출된 비밀번호 해시를 찾게 되면 데이터베이스에서 색인을 수행해 사전에 연산된 해시와 일치하는지 확인하면 된다. 솔트 비밀번호도 결과 해시가 바뀌기 때문에 이런 공격이 비효율적이게 된다.

또한 솔트는 공격자가 데이터베이스에서 중복된 데이터베이스를 발견하지 못하도록 한다. 2명 이상의 사용자가 같은 비밀번호를 선택하더라도 서버가 다른 솔트를 생성해 해시가 다르게 된다. 솔트를 최소 16글자 길이로 하면 컴퓨팅 집약적인 무차별 대입 방법으로 해킹해야 하는 평문 문자열의 복잡성과 길이가 크게 증가한다.

솔트 외에 또 다른 보안 계층을 추가하기 위해 개발자는 모든 비밀번호와 페퍼(Pepper)라는 무작위로 생성된 최소 32글자의 문자열을 조합할 수 있다. 모든 비밀번호에 고유한 솔트와 달리 페퍼는 모든 비밀번호에 동일하지만 데이터베이스 안에 저장하지 않아야 한다. 페퍼의 목적은 공격자가 솔트를 포함해 애플리케이션 전체 데이터베이스를 획득하더라도 해킹이 어렵도록 하는 것이다.

페퍼는 적절한 파일 시스템 권한으로 보호되는 애플리케이션 구성 파일 또는 HSM(Hardware Security Module) 등의 더욱 안전한 장소에 보관할 수 있다. OWASP는 “대체 접근방식은 평상시처럼 비밀번호를 해시 처리한 후 해시를 데이터베이스에 저장하기 전에 대칭 암호화 키를 사용해 암호화하는 것이다. 키가 페퍼로 작용한다. 이를 통해 페퍼에 대한 전통적인 접근방식의 문제 가운데 일부를 피할 수 있으며 페퍼가 해킹되었을 경우 훨씬 쉽게 전환할 수 있다”라고 설명했다. 


해시 업그레이드하기 

안전하지 못하거나 약한 해싱 알고리즘을 사용하는 애플리케이션은 최신 해싱 함수로 전환해야 한다. 전환 방법 가운데 하나는 기존의 해시를 새 해싱 알고리즘의 입력값으로 사용해 기존의 해시를 재해싱하는 것이다. 이 방법을 통해 즉각적인 문제는 해결할 수 있지만 본래의 사용자 입력으로부터 해시를 생성한 경우보다 해킹에 취약하다.

따라서 차후에 사용자가 로그인하고 비밀번호를 입력할 때 새 최신 알고리즘으로 해시를 다시 생성하는 것이 좋다. 사용자가 일정 기간 동안 로그인하지 않는 경우 비밀번호를 재설정하고 다음 번에 로그인할 때 강제로 비밀번호를 재설정하도록 할 수 있다.

마지막으로 암호 기법을 사용하는 모든 개발자의 황금률이다. '자신만의 알고리즘을 개발하지 말라'. 암호 기법은 매우 어렵고 표준화되고 널리 사용되는 알고리즘은 일반적으로 다른 암호 기법 전문가와 분석가의 동료 심사를 받는 학문적 연구의 결과물이다. editor@itworld.co.kr

회사명 : 한국IDG | 제호: ITWorld | 주소 : 서울시 중구 세종대로 23, 4층 우)04512
| 등록번호 : 서울 아00743 등록발행일자 : 2009년 01월 19일

발행인 : 박형미 | 편집인 : 박재곤 | 청소년보호책임자 : 한정규
| 사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.