사전 SHA-1
알고리즘

SHA-1

gabury1고친 사람 github-actions[bot]

SHA-1 은 길이가 얼마든 상관없는 데이터를 짧은 값 하나로 줄여 그 데이터를 가리키는 이름으로 씁니다. 같은 데이터를 넣으면 언제나 같은 값이 나오고, 한 글자만 달라져도 값이 통째로 달라집니다. 그래서 파일이 바뀌었는지 가려내거나 데이터마다 이름을 붙이는 데 오래 쓰였습니다. 지금은 속이려는 사람을 막아야 하는 곳에서는 쓰지 않습니다.

쉽고 빠른 이해

SHA-1 은 어떤 데이터든 받아서 40자리 16진수 하나로 바꿔 줍니다. 파일 하나를 넣으면 그 파일을 가리키는 짧은 이름이 나오는 셈입니다.

이게 없으면 두 데이터가 같은지 보려고 처음부터 끝까지 맞대 봐야 합니다. 짧은 값으로 줄여 두면 값끼리만 견주면 됩니다.

어떻게 도나:

  1. 데이터 뒤에 정해진 규칙대로 채움 값을 붙여 길이를 맞춥니다
  2. 그것을 같은 크기 조각으로 쪼개고, 조각을 하나씩 섞어 내부 값을 계속 바꿉니다
  3. 조각을 다 먹고 남은 내부 값이 그 데이터의 SHA-1 값입니다

대가는 출력 길이입니다. 나올 수 있는 값의 가짓수가 정해져 있어 서로 다른 데이터가 같은 값을 갖는 일을 못 막습니다. SHA-1 은 그 겹치는 쌍을 일부러 만들어 내는 방법까지 알려져서 서명처럼 속임을 막아야 하는 곳에서 물러났습니다.

상세

SHA-1 은 Secure Hash Algorithm 1 의 줄임말입니다. 우리말로 옮기면 안전한 해시 알고리즘 1 입니다. 무엇을 넣어도 언제나 160비트짜리 값 하나를 내놓습니다.

이런 함수를 해시 함수라고 부릅니다. 해시 함수는 길이가 제각각인 데이터를 짧은 값 하나로 줄이는 함수이고, 그 값을 해시값이라고 합니다. 그중에서도 속이려는 사람이 있다고 보고 만든 것이 암호학적 해시 함수이며 SHA-1 이 여기에 듭니다.

이 절은 먼저 SHA-1 이 무엇을 받아 무엇을 내놓는지 봅니다. 그다음 안을 열어 어떤 순서로 도는지 보고, 왜 지금은 안전하다고 보지 않는지, 그런데도 아직 어디에 남아 있는지를 봅니다.

입력과 출력

입력에는 제한이 거의 없습니다. 짧은 문자열도 받고 큰 파일도 그대로 받습니다. 출력은 반대로 언제나 같은 길이입니다. 입력이 한 바이트든 수 기가바이트든 나오는 값은 160비트입니다.

160비트는 20바이트입니다. 16진수로 적으면 한 바이트가 두 자리를 차지하므로 40자리 문자열이 됩니다. 아래는 문자열 하나를 해시해 길이만 확인해 본 것입니다.

Python
h = sha1(b"hello")
h.digest()      # 20바이트
h.hexdigest()   # 40자리 문자열

같은 입력에는 언제나 같은 값이 나옵니다. 되돌리는 길은 없습니다. 해시값에서 원래 데이터로 돌아가는 계산은 마련되어 있지 않습니다.

출력 길이는 함수마다 다릅니다. 이름 뒤에 붙은 숫자가 그 길이를 가리키는 경우가 많습니다.

함수 출력 비트 16진수 자릿수
MD5(Message-Digest algorithm 5) 128 32
SHA-1 160 40
SHA-256(Secure Hash Algorithm 256) 256 64

표에서 SHA-1 은 가운데에 있습니다. MD5 보다는 길고 SHA-256 보다는 짧습니다. 이 길이 차이가 뒤에서 볼 안전성 이야기의 바탕이 됩니다.

어떻게 도나

SHA-1 은 데이터를 한꺼번에 계산하지 않습니다. 정해진 크기로 쪼개서 하나씩 먹습니다. 조각 하나의 크기는 512비트입니다.

먼저 길이를 맞춥니다. 데이터 끝에 정해진 규칙대로 채움 값과 원래 길이를 붙여 전체가 512비트의 배수가 되게 만듭니다. 이 작업을 패딩이라고 합니다.

그다음 160비트짜리 내부 값을 하나 놓고 시작합니다. 시작 값은 정해진 상수입니다. 조각을 하나 읽을 때마다 이 값을 섞어 새 값으로 바꾸는데, 섞는 계산은 한 조각당 여든 번 되풀이됩니다.

flowchart TD
    IV["시작 값 · 160비트"] --> C1["조각 1 을 섞는다"]
    C1 --> C2["조각 2 를 섞는다"]
    C2 --> C3["마지막 조각을 섞는다"]
    C3 --> OUT["남은 내부 값 · 해시값"]

그림에서 볼 것은 내부 값 하나가 끝까지 이어진다는 점입니다. 조각마다 새로 시작하는 것이 아니라 앞 조각이 남긴 값 위에 다음 조각을 얹습니다. 이렇게 조각을 차례로 먹으며 상태를 갱신하는 얼개를 머클-담고르 구조라고 부릅니다. MD5 도 같은 얼개를 씁니다.

섞는 계산에 바라는 성질이 눈사태 효과입니다. 입력을 한 비트만 바꿔도 출력 비트가 절반쯤 달라져야 합니다. 비슷한 입력이 비슷한 출력을 내면 출력을 보고 입력을 짐작할 실마리가 생깁니다.

왜 더는 안전하다고 보지 않나

출력 길이가 정해져 있으니 서로 다른 데이터가 같은 해시값을 갖는 일은 반드시 생깁니다. 이렇게 겹치는 쌍을 충돌이라고 합니다.

암호학적 해시 함수가 요구하는 것은 충돌이 없는 것이 아닙니다. 충돌하는 쌍을 계산으로 찾아내기가 현실적으로 불가능한 것입니다. 이 요구를 충돌 저항성이라고 부릅니다.

찾기 어려움에는 출력 길이로 정해지는 상한이 있습니다. 생일 문제가 그 상한을 알려 줍니다. 출력이 160비트면 값의 가짓수는 2의 160제곱이지만, 아무 데이터나 2의 80제곱 개쯤 해시해 보면 겹치는 쌍이 나올 가능성이 커집니다.

SHA-1 의 문제는 그 상한보다 훨씬 적은 계산으로 충돌을 만드는 방법이 밝혀졌다는 것입니다. 나중에는 서로 다른 두 파일이 같은 SHA-1 값을 갖는 실물까지 공개됐습니다. 계산으로는 못 찾는다는 전제가 깨진 셈입니다.

그래서 서명이나 인증서처럼 속임을 막는 것이 목적인 곳에서는 SHA-1 을 쓰지 않습니다. 새로 고르는 경우에는 출력이 더 긴 SHA-256 을 씁니다.

아직 SHA-1 이 남아 있는 곳

Git 은 커밋과 파일에 이름을 붙일 때 SHA-1 값을 씁니다. 내용을 해시해서 그 값을 그대로 이름으로 삼는 방식입니다. 여기서 해시값이 하는 일은 서명이 아니라 이름표입니다.

이름표로 쓰는 것과 서명에 쓰는 것은 요구가 다릅니다. 서명은 공격자가 같은 값을 갖는 가짜를 만들면 곧바로 뚫립니다. 이름표는 실수로 생기는 겹침만 없으면 대체로 굴러갑니다.

그렇다고 안심할 수 있는 것은 아닙니다. 공격자가 저장소에 파일을 밀어 넣을 수 있다면 이름표 용도도 표적이 됩니다. Git 이 이름 체계를 SHA-256 으로 옮기는 작업을 해 온 까닭이 여기 있습니다.

체크섬이나 머클 트리처럼 데이터가 도중에 깨졌는지 보는 용도도 사정이 비슷합니다. 실수로 생긴 손상을 잡는 데는 아직 쓸 만합니다. 다만 새로 짜는 코드라면 굳이 SHA-1 을 고를 이유가 없습니다.

비밀번호에는 쓰지 않는다

비밀번호를 저장할 때 SHA-1 을 그냥 쓰면 안 됩니다. 충돌 이야기 이전에 계산이 너무 빨라서입니다. 공격자도 후보를 그만큼 빨리 대입해 볼 수 있습니다.

이런 곳에는 일부러 계산이 오래 걸리게 만든 비밀번호 해싱 함수를 씁니다. 그리고 사용자마다 다른 임의 값을 함께 섞는데, 그 값을 솔트라고 합니다. 이 이야기는 SHA-256 으로 바꿔도 그대로입니다.

언제 쓰고 언제 안 쓰나

지금까지 본 것을 쓰임별로 모으면 이렇습니다.

쓰임 SHA-1 로 괜찮나
전자 서명 · 인증서 안 됩니다
비밀번호 저장 안 됩니다. 어느 해시 함수든 그냥 쓰면 안 됩니다
내용에 이름 붙이기 이미 그렇게 도는 시스템이면 남아 있습니다
전송 중 손상 확인 실수로 생긴 손상에는 쓸 수 있습니다
새로 고르는 경우 SHA-256 이나 그보다 새 함수를 고릅니다

가르는 기준은 하나입니다. 값을 맞춘 가짜를 누가 일부러 만들 수 있는 상황인가입니다. 그런 상황이면 SHA-1 은 후보가 아닙니다.

관련 항목

SHA-1 이 속하는 상위 분류

해시 함수 · 암호학적 해시 함수 · 해시 · 다이제스트

SHA-1 을 대신하는 해시 함수

SHA-256 · SHA-2 · SHA-3 · BLAKE2 · MD5

SHA-1 이 지켜야 할 성질

충돌 저항성 · 역상 저항성 · 제2 역상 저항성 · 눈사태 효과 · 생일 문제

SHA-1 을 이루는 계산 얼개

머클-담고르 구조 · 압축 함수 · 패딩 · 비트 연산

SHA-1 을 이름표와 무결성에 쓰는 도구

Git · 커밋 · 버전관리 · 머클 트리 · 체크섬 · 무결성

SHA-1 이 물러난 보안 용도

전자 서명 · 인증서 · 인증 기관 · TLS · HMAC

비밀번호 저장에 대신 쓰는 함수

비밀번호 해싱 · 솔트 · bcrypt · Argon2 · PBKDF2 · 레인보우 테이블

다른 이름: SHA1 · Secure Hash Algorithm 1