본문 바로가기
스마트홈 보안

내 비밀번호는 과연 안전한가? : 해시, 솔트, 페퍼

by 오토맨 2025. 7. 18.

암호화되어 있습니다라는 문장의 허상

 

내 비밀번호는 과연 안전한가? : 해시, 솔트, 페퍼

 

 

우리는 일상적으로 다양한 웹서비스에 가입하고 로그인한다. 그 과정에서 익숙하게 마주치는 문장이 있다. “회원님의 비밀번호는 안전하게 암호화되어 저장됩니다.” 얼핏 들으면 마치 철통 보안 아래에 보관되는 것처럼 느껴지지만, 실상은 그리 단순하지 않다.

2024년 한 해 동안에도 수많은 기업이 고객의 개인정보를 유출했고, 그 중에는 “암호화를 했다”고 주장한 곳도 있었다. 그러나 정작 유출된 비밀번호는 공격자에 의해 빠르게 복구되었고, 그 피해는 고스란히 사용자에게 돌아갔다. 이는 곧 “암호화했다”는 문장이 실제로 어떤 방식으로 이뤄졌는지에 따라 보안 수준이 천차만별이라는 것을 의미한다.

비밀번호 보안은 단순한 기술이 아니다. 해커의 관점에서 다시 생각해 보면, ‘무엇을’ 썼느냐보다 ‘어떻게’ 구현했는지가 관건이다. 이 글에서는 단방향 해시(Hash)의 개념부터, 그것의 한계를 보완하는 솔트(Salt)와 페퍼(Pepper), 그리고 현대적인 보안 기법인 키 스트레칭(Key Stretching)까지, 실제 해킹 기법과 대응 방식을 바탕으로 깊이 있는 설명을 제공한다.


비밀번호는 어떻게 안전하게 저장되어야 하는가?

1. 해시(Hash): 비밀번호를 ‘되돌릴 수 없게’ 만드는 기술

해시는 임의의 길이를 가진 데이터를 일정한 길이의 난수로 바꿔주는 변환 방식이다. 이 과정을 단방향 함수라 부르며, 그 본질은 ‘복호화 불가능’에 있다. 예를 들어 password123이라는 문자열을 SHA-256 해시 알고리즘에 통과시키면, 다음과 같은 긴 무작위 문자열이 출력된다:

ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f

 

이 값은 절대로 다시 password123으로 역산될 수 없다. 서버는 이 해시값만 저장해 두고, 사용자가 로그인할 때 입력한 비밀번호를 같은 방식으로 해시하여 비교하는 것이다. 이러한 설계는 서버가 해킹당하더라도 원문 비밀번호가 곧바로 노출되지 않게 하기 위한 최소한의 조치다.

하지만 중요한 사실은 해시 알고리즘만으로는 보안이 충분하지 않다는 것이다.


2. 해시만으로는 부족하다 – 레인보우 테이블과 GPU 공격

레인보우 테이블(Rainbow Table) 공격

레인보우 테이블이란 수많은 일반적인 비밀번호와 그 해시값을 미리 계산해 놓은 거대한 참조표이다. 해커는 이런 테이블을 이용하여, 유출된 해시값이 어떤 평문 비밀번호에서 생성되었는지를 순식간에 역산할 수 있다. 예를 들어, 5f4dcc3b5aa765d61d8327deb882cf99라는 해시값은 password라는 문자열의 MD5 해시라는 사실이 널리 알려져 있다. 이처럼 해시는 고유성이 없고, 같은 입력에는 항상 같은 출력이 생성되므로 테이블화가 가능하다.

 

 

고속 연산 기반의 무차별 대입(Brute-force) 공격

한편, GPU나 ASIC, FPGA 같은 병렬 처리 가능한 하드웨어의 발전은 해시 계산 속도를 비약적으로 증가시켰다. 과거에는 초당 수백만 번의 비밀번호 대입이 가능했다면, 이제는 초당 수십억 건 이상이 현실화되었다. 클라우드 인프라를 악용하면 개인도 이러한 연산을 손쉽게 수행할 수 있다. 따라서 단순한 해시만으로 보호된 비밀번호는 사실상 평문과 다름없을 수 있다.


3. 솔트(Salt): 같은 비밀번호라도 다르게 만드는 기술

솔트는 사용자가 입력한 비밀번호에 무작위의 고유 문자열을 덧붙여 해시함으로써, 비슷한 비밀번호라도 서로 다른 결과값을 생성하게 하는 방식이다. 다음 예를 보자:

  • 사용자 A: password123 + XyZ82!k
  • 사용자 B: password123 + aB1@cDe

비밀번호는 같지만, 솔트가 다르면 해시 결과도 완전히 다르다. 솔트를 통해 레인보우 테이블 공격은 원천 차단되며, 해커는 각 솔트 조합에 맞는 새로운 테이블을 일일이 계산해야 하므로 공격 효율이 극적으로 저하된다. 대부분의 현대적인 웹서비스에서는 사용자의 계정마다 고유한 솔트를 저장하고 있다. 그러나 여전히 솔트 없이 구식 해시만 사용하는 경우도 존재하기에 경계를 늦춰서는 안 된다.


4. 키 스트레칭과 페퍼(Pepper): 고도화된 공격에 대한 방패

▣ 키 스트레칭(Key Stretching): 느림을 무기로 삼다

키 스트레칭은 ‘해시를 반복 수행하여 의도적으로 연산을 느리게 만드는 것’이다. 해커의 GPU가 초당 수십억 건의 대입을 시도한다면, 그 연산 하나하나에 시간 지연을 걸어 전체 계산 속도를 늦추는 것이다. 대표적인 구현 알고리즘으로는 Bcrypt, Scrypt, PBKDF2, Argon2 등이 있다. 이 방식은 사용자의 로그인에는 지장이 없을 정도로만 느리게 만들되, 대량 공격에는 치명적인 속도 저하를 유발하도록 설계되어 있다.

▣ 페퍼(Pepper): 보이지 않는 비밀의 마지막 퍼즐

페퍼는 솔트와는 달리, 모든 사용자에게 동일하게 적용되는 ‘사이트 전체의 비밀 키’이다. 페퍼는 일반적으로 소스 코드 내부나 별도의 보안 키 관리 시스템(KMS)에 저장되며, 유출 위험이 높은 데이터베이스에는 보관되지 않는다. 즉, 해커가 설령 데이터베이스 전체를 획득하더라도, 페퍼가 없으면 비밀번호 해시를 유효하게 계산할 수 없다. 이는 보안 방어의 이중화와 분산화 전략에 해당하며, 서버-데이터베이스 간 책임 분리 구조를 통해 보안성을 한층 강화할 수 있다.


5. 비밀번호 저장의 모범 사례

현재 업계에서 가장 안전하다고 인정되는 비밀번호 저장 방식은 다음과 같은 절차를 따른다:

  1. 암호학적으로 안전한 솔트 값을 생성 (고유, 사용자별)
  2. 서버 측에서 보유한 페퍼 값을 비밀번호에 결합
  3. 키 스트레칭 알고리즘(예: Argon2id)으로 수만 번 반복 처리
  4. 최종 해시값만을 데이터베이스에 저장

최종 저장 형식:

Argon2id(비밀번호 + 사용자별 솔트 + 페퍼, 반복 횟수)

이러한 구조를 갖추면, 데이터 유출이 발생하더라도 해커가 실질적으로 비밀번호를 복구하는 데는 천문학적인 시간과 자원이 필요해진다.


사용자가 해야 할 일, 그리고 보안의 본질

 

비밀번호 보안은 단지 시스템의 문제만이 아니다. 사용자 또한 보안의 한 축을 담당한다. 비밀번호가 아무리 복잡하게 저장된다 해도, 사용자가 같은 비밀번호를 여러 사이트에 반복해 사용하는 순간 위험은 기하급수적으로 커진다. 한 곳에서의 유출이 도미노처럼 전체 계정 탈취로 이어질 수 있기 때문이다.

다음은 사용자가 실천할 수 있는 현실적인 보안 수칙이다:

  • 비밀번호 관리자 사용: 기억할 필요 없는 고강도 무작위 비밀번호를 각 사이트마다 다르게 생성하고 안전하게 보관할 수 있다.
  • 이중 인증(2FA/MFA) 활성화: 비밀번호가 유출되더라도, 물리적 소지(스마트폰) 없이는 계정에 접근할 수 없도록 한다.
  • 비밀번호 재사용 금지: 유출된 데이터가 다른 계정 해킹에 악용되지 않도록 반드시 서로 다른 비밀번호를 사용해야 한다.

보안은 책임이 아니라 선택이다

 

 

오늘날의 디지털 환경에서는 보안이 선택이 아니라 생존의 문제로 여겨지고 있다. 비밀번호는 개인의 디지털 정체성을 보호하는 마지막 보루이며, 그것이 허술할 경우 당신의 삶 전반에 치명적인 영향을 미칠 수 있다.

‘암호화되었다’는 말만 믿기보다는, 해시의 방식, 솔트의 유무, 키 스트레칭의 적용 여부, 페퍼의 존재 여부까지 종합적으로 따져볼 필요가 있다. 기술이 아무리 정교해져도, 사용자의 관심과 행동이 없다면 그것은 무용지물이다. 정보 보안은 결국, 기술과 사람이 함께 완성해야 할 공동의 책임이자 약속이다.