109. 키 스트레칭 (Key Stretching) & 패스워드 해싱 함수

⚠️ 이 문서는 해시 함수(SHA-256)의 "연산 속도가 너무 빠르다"는 장점이 오히려 무차별 대입 공격에 치명적인 약점이 되자, 해시를 수만 번 반복해서 돌려 고의로 연산 속도를 느리게 만들고 해커의 GPU를 혹사시키는 최후의 패스워드 방어 아키텍처를 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 키 스트레칭(Key Stretching)은 패스워드와 솔트(Salt)를 섞은 데이터를 해시 믹서기에 한 번만 돌리고 끝내는 것이 아니라, 튀어나온 결과를 다시 믹서기에 넣는 짓을 수만 번에서 수십만 번 반복하여 패스워드 검증에 걸리는 시간을 고의로 지연시키는 방어 기법이다.
  2. 가치: 정상 사용자가 로그인할 때 0.1초가 걸리는 것은 아무 불편함이 없지만, 초당 1,000억 개의 해시를 돌리던 해커의 그래픽카드(GPU) 봇넷에게 이 0.1초의 지연은 1명을 해킹하는 데 10년이 걸리게 만드는 지옥의 브레이크로 작용한다.
  3. 융합: 이 기법을 구체화한 알고리즘으로 표준인 PBKDF2, 블로피시(Blowfish) 암호 기반의 대중적인 Bcrypt, 그리고 해커의 주문형 반도체(ASIC) 공격을 막기 위해 메모리(RAM) 자원까지 강제로 갉아먹게 설계된 Scrypt와 Argon2가 진화의 계보를 잇고 있다.

Ⅰ. 개요 및 필요성 (해시의 속도 역설)

2010년대, 솔트(Salt)를 치면 레인보우 테이블(커닝 페이퍼)은 무용지물이 되었다. 암호학자들은 안심했다. 하지만 해커들은 무식한 정공법을 택했다. 최신 3D 게임을 돌리려고 만든 엔비디아(NVIDIA) 그래픽카드 수십 장을 병렬로 연결해 엄청난 연산력의 괴물을 만든 것이다. SHA-256 같은 표준 해시 함수는 하드웨어 연산 효율이 너무 극대화되어 있어, 해커의 괴물 컴퓨터는 1초에 1,000억 번의 해시를 무자비하게 돌려버린다. (무차별 대입 공격)

유저 A의 솔트가 X9!@ 라면, 해커는 1234 + X9!@, 1235 + X9!@ 를 실시간으로 믹서기에 갈아버린다. 방어막이 5분도 안 되어 산산조각 났다.

암호학자들의 천재적인 발상의 전환: "해시 함수가 너무 빨라서 털린다면, 무식하게 계산을 10만 번 반복하게 만들어서 해커 컴퓨터의 시간(Time)과 전기세를 말려 죽여버리자!" 이것이 비밀키를 길고 질기게 잡아당겨 늘린다는 뜻의 **키 스트레칭(Key Stretching)**이다.

📢 섹션 요약 비유: 해커가 스포츠카(GPU)를 타고 1초 만에 은행 털러 오는 걸 막기 위해, 은행 앞 도로에 10만 개의 과속 방지턱(키 스트레칭)을 깔아버린 것입니다. 정상 고객은 하루에 한 번 방지턱을 넘으니 조금 덜컹거려도 참을 수 있지만, 1초에 10만 번 은행을 들락거려야 하는 도둑은 차가 아예 박살 나서 공격을 포기하게 됩니다.


Ⅱ. 대표적인 패스워드 해싱 함수 (KDF, Key Derivation Function)

개발자가 반복문(for 문)으로 직접 SHA-256을 10만 번 돌리도록 코딩하면 보안 결함이 생길 수 있다. 따라서 암호학계가 만들어둔 표준 검증된 함수들을 그대로 가져다 써야 한다.

1. PBKDF2 (Password-Based Key Derivation Function 2)

  • 개념: 미국 국립표준기술연구소(NIST)의 공식 표준 알고리즘.
  • 구조: PBKDF2(해시엔진, 패스워드, 솔트, 반복횟수, 출력길이)
  • 평문 패스워드에 솔트를 더하고, 10만 번 이상 해시(주로 HMAC-SHA256 사용)를 반복해서 결과를 뽑아낸다. 공식 표준이라 가장 무난하지만, 최신 GPU 공격에는 다소 밀리는 경향이 있다.

2. Bcrypt (비크립트) - 가장 대중적인 강자

  • 개념: 1999년 만들어진, 블로피시(Blowfish)라는 대칭키 암호화 알고리즘을 역으로 비틀어 해시 함수처럼 만든 걸작. 현재 수많은 백엔드 프레임워크(Spring, Node.js 등)의 기본 비밀번호 인코딩 함수다.
  • 장점 (Cost Factor): work factor(cost)라는 변수를 제공한다. 이 값을 10에서 12로 올릴 때마다 연산 시간이 기하급수적으로 늘어난다. 내일모레 더 빠른 컴퓨터가 나오면, 코드를 안 고치고 이 cost 숫자만 13으로 올려주면 방어력이 다시 무적이 되는 엄청난 확장성을 가졌다.

3. Scrypt (스크립트) - 메모리 하드(Memory-Hard) 방어

  • 위협의 진화: 해커들이 GPU를 넘어 비트코인 채굴기처럼 오직 해시만 빠르게 푸는 깡통 전용 칩셋(ASIC/FPGA)을 깎아서 들이밀기 시작했다.
  • 대응책 (Scrypt): 칩셋 연산이 아무리 빨라도 메모리(RAM)를 억지로 몇 백 메가바이트(MB)씩 갉아먹게 만들어버린 미친 알고리즘이다. 해커가 ASIC 칩을 수천 개 꽂아서 해킹하려 해도, 메모리(RAM) 수천 기가가 통째로 불타버리기 때문에 기계 제작 단가가 수백억 원으로 치솟아 해킹을 원천 포기하게 만든다.

4. Argon2 (아르곤2) - 현재 지구상 최고 존엄

  • 2015년 전 세계 패스워드 해싱 대회(PHC)에서 우승한 현존 최고의 함수.
  • 연산 시간(Time), 메모리 소모량(Memory), 병렬 처리 개수(Parallelism) 이 세 가지를 개발자가 원하는 대로 튜닝하여 극한의 밸런스를 맞출 수 있는 현대 암호학의 결정체다.
┌───────────────────────────────────────────────────────────────────────────┐
│           단순 해시 vs 키 스트레칭(Bcrypt 등)의 해킹 소요 시간 시각화     │
├───────────────────────────────────────────────────────────────────────────┤
│                                                                           │
│ [ 1. 옛날 서버: 단순 SHA-256 사용 ]                                       │
│  유저 1명 로그인(1번 해시) 걸리는 시간: 0.000001초                        │
│  ☠️ 해커의 공격: 최고급 GPU로 초당 1,000억 개 비번 찍어 맞추기 가능!      │
│    -> (결과) 8자리 비밀번호 5분 만에 전면 함락!                           │
│                                                                           │
│ [ 2. 현대 서버: 키 스트레칭(Bcrypt cost=12) 10만 번 반복 적용 ]           │
│  유저 1명 로그인(10만 번 해시) 걸리는 시간: 0.1초 (정상 유저는 못 느낌)   │
│  🛡️ 해커의 좌절: 1번 대입할 때마다 0.1초씩 기다려야 함.                   │
│    해커 GPU: "헉헉... 1개 맞추는데 0.1초나 걸려... 1,000억 개 하려면..."  │
│    -> (결과) 8자리 비밀번호 하나 푸는 데 300년 소요! 해킹 100% 포기.      │
└───────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 암호학에서 연산 지연(Delay)을 일부러 무겁게 세팅하는 유일한 분야가 바로 비밀번호 해싱이다. 로그인할 때 0.1초~0.5초 정도 서버가 고민하는 것은 고객의 답답함을 유발하지 않는다. 하지만 해커는 1개의 정답을 찾기 위해 이 0.1초를 수십억 번 반복(수억 초)해야 하므로, 공격자의 물리적 시간과 금전적 비용을 파탄 내버리는 완벽한 '비대칭 방어'가 성립한다.

  • 📢 섹션 요약 비유: 금고 문을 딸 때, 옛날엔 열쇠를 구멍에 쑥 넣으면 바로 돌아갔습니다. 키 스트레칭은 열쇠 구멍 안을 아주 뻑뻑한 꿀로 가득 채운 금고입니다. 진짜 주인은 아침에 한 번만 낑낑대며 문을 열면 되지만, 밤새도록 수만 개의 가짜 열쇠를 돌려봐야 하는 도둑은 팔이 부러져서 도망갈 수밖에 없습니다.

Ⅲ. 실무 적용 및 안티패턴 (절대 하면 안 되는 실수)

  • 프론트엔드(Client-side) 해싱의 저주: "서버 CPU 부담 줄이려고, 브라우저(웹) 자바스크립트에서 Bcrypt 10만 번 돌려서 해시값을 서버로 보냈어요!" $\rightarrow$ 최악의 설계. 해커가 그 해시값 자체를 비밀번호처럼 가로채서(Pass-the-Hash) 서버에 던지면 그대로 통과된다. 키 스트레칭은 무조건 백엔드 서버 깊숙한 곳에서 자체 CPU 자원을 태워가며 수행해야 한다.

  • 반복 횟수의 최신화 방치: 5년 전에 PBKDF2 반복 횟수를 1만 번으로 세팅하고 잊어버린 시스템. 5년 뒤 그래픽카드는 10배 빨라졌다. 서버 엔지니어는 매년 보안 권고안(NIST)을 모니터링하며 이 반복 횟수(또는 cost)를 10만 번, 30만 번으로 계속 상향 업데이트하는 스크립트를 짜둬야 한다.


Ⅳ. 결론

"보안의 궁극적인 승리는 창을 부러뜨리는 것이 아니라, 적의 지갑을 비우는 것이다." 키 스트레칭과 메모리 하드 해싱(Scrypt, Argon2)은 해커의 '기술력'을 꺾는 것이 아니라 해커의 '경제력(연산 비용)'을 파산시켜 버리는 매우 경제학적인 방어 모델이다. 아무리 수학적으로 결함이 없는 암호라도, 컴퓨팅 파워의 폭주 앞에서는 속수무책이다. 이 단순하지만 무식한 10만 번의 반복(Work Factor)이야말로 오늘날 전 세계 수십억 명의 고객 비밀번호가 어둠의 바다로 유출되는 것을 막고 있는 최후의 방벽이다.


📌 관련 개념 맵

  • 방어하려는 공격: 브루트 포스(무차별 대입 공격), 사전 공격, ASIC/GPU 가속 공격
  • 필수 짝꿍 기술: 솔트 (Salt, 레인보우 테이블 방어용)
  • 대표 알고리즘 계보: PBKDF2 (표준) $\rightarrow$ Bcrypt (대중적) $\rightarrow$ Scrypt (메모리 하드) $\rightarrow$ Argon2 (최강)
  • 보안 공학의 목표: Work Factor (작업 증명 비용) 증대

👶 어린이를 위한 3줄 비유 설명

  1. 컴퓨터가 엄청 빨라져서 해커들이 1초에 1천억 번씩 번호를 찍어 맞춰서 우리 비밀번호를 알아내는 끔찍한 시대가 왔어요.
  2. 그래서 똑똑한 아저씨들이 비밀번호 자물쇠에 다가 "한 번 돌릴 때마다 무조건 0.1초 동안 기다려야 열린다!"라는 강제 브레이크(키 스트레칭)를 달아놨어요.
  3. 주인은 아침에 0.1초만 기다리면 되지만, 1천억 번을 돌려봐야 하는 나쁜 해커는 번호를 다 찍어보려면 300년이 걸려서 결국 해킹을 포기하고 엉엉 울면서 집에 돌아갔답니다!