암호화, bcrypt를 만나다⚡️(feat.해시함수)

Yoonmin·2024년 12월 11일
0

보안

목록 보기
1/2
post-thumbnail

너는 누구냐, bcrypt🧐

bcrypt란 암호화 라이브러리이다.
🚨우리는 먼저 사전 지식을 알아보고 가보도록하자🚨

✨사전 지식[해시, 해시함수, 복호화, 암호화]

비밀 번호를 안전하게 해시(hash) 처리하여 데이터 베이스에 저장할때 사용된다.
해싱된 값은 복호화가 불가능하고, 비교를 통해 비밀번호를 검증해야한다.

✅ 해시 함수? 해싱? 복호화? 너는 누구?

해시 함수는 무엇인가요? 토스페이먼츠 해싱 함수 이미지

[출처 | 토스페이먼츠 개발자 센터]

📲 입력값

해시 함수의 입력 값은 '메시지' 라고 부릅니다.
입력값으로 다양한 길이와 형태의 데이터가 사용됩니다.
단일 문자, 음악파일, 메시지뿐만 아니라 복잡한 데이터 구조도 입력 가능합니다.

또한 해시 함수는 입력 데이터를 특정 알고리즘에 따라 고정된 길이의 해시값으로 변환하는데,
이 과정에서 데이터는 내부적으로 이진수로 처리가 처리됩니다.

//Hello ASCII code 변환 ASCII code 이진수로 변환
"H" -> ASCII: 72 -> Binary: 01001000
"e" -> ASCII: 101 -> Binary: 01100101
"l" -> ASCII: 108 -> Binary: 01101100
"o" -> ASCII: 111 -> Binary: 01101111
//Hello 이진수 도출 값
01001000 01100101 01101100 01101100 01101111

🔐 해시 함수

해시 함수는 입력값을 고정된 크기의 블록으로 나눈 다음에 수학적 연산을 적용해 최종 해시를 출력한다.
[출처 | 업비트 투자자보호센터]

해시 함수는 주어진 입력에 대해 항상 동일한 해시를 생성하고

이미지와 상단과 같은 해시함수 입력시, 같은 출력 값 도출

입력 데이터조금이라도 바뀌어도 출력값은 크게 달라집니다.

이미지와 하단과 같이 해시함수 입력시 상단과 크게 다른 값 출력

좋은 해시 함수는 효율적이며 다른 입력이 동일한 해시를 생성하는 것을 거의 불가능하게 합니다. 이런 특성 때문에 해시를 데이터 비교 및 무결성에 안전하게 사용할 수 있습니다.

대표적으로 사용되는 해시 함수는 다음과 같습니다.

  • 암호화 해시 함수(Cryptographic Hash Functions)
    비밀번호 보관, 디지털 서명 등 보안 관련 용도로 사용되는 해시 함수입니다.
    대표적으로는 SHA-256, SHA-3, MD5 함수가 있죠.
  • 비암호화 해시 함수(Non-cryptographic Hash Functions)
    데이터 인덱싱 또는 해시 테이블과 같이 보안보다 효율이 필요할 때 사용되는 해시 함수입니다.
    대표적으로는 MurmurHash, CityHash 함수가 있죠.

📤 출력값

해시 함수의 출력값'해시' 또는 '다이제스트'라고도 합니다.
입력값고유한 출력값이 생성되기 때문에 지문과 비슷하다고 생각할 수 있습니다.

출력값의 길이는 해시 함수에 따라 달라지는데 예를 들어 SHA-256 해시 함수는 항상 265비트의 출력값을 생성합니다.
[출처 | 업비트 투자자보호센터]

✅ 해싱

해싱은 암호화와 달리 출력값원본 입력값으로 복호화할 수 없습니다.
출력값은 항상 고정된 길이의 문자열을 출력하기 때문에 입력 데이터가 손실되고, 출력값과 해싱 함수를 안다고 해도 대응하는 입력값을 찾는 것은 매우 어려운 일입니다.

🧐 그럼 해싱은 언제 필요하죠?
✨ 해시 함수는 다양한 분야에서 중요한 역할을 하고 있어요.

  • 데이터 무결성
    해시 함수로 데이터가 조작되지 않았는지 검증할 수 있습니다.
    예를 들어, 파일을 다운로드하면 파일과 함께 해시가 제공됩니다.
    다운로드 파일을 해싱해서 나오는 출력값과 다운로드할 때 받은 해시와 비교하면 데이터 무결성을 확인할 수 있습니다.

  • 디지털 서명
    암호화 해시 함수로 메시지나 문서에 디지털 서명을 추가할 수 있습니다.
    디지털 서명은 메시지 전송자의 신원을 증명하고 내용이 변조되지 않았음을 보증합니다.
    전송자는 메시지의 해시를 암호화해서 디지털 서명을 생성하고, 수신자는 디지털 서명을 복호화한 다음에 수신한 메시지의 해시와 비교합니다.

  • 비밀번호 저장
    대부분의 서비스는 사용자의 실제 비밀번호를 서버에 저장하지 않습니다.
    대신 비밀번호의 해시를 저장합니다.
    서버가 해킹되어도 실제 비밀번호가 노출되지 않기 때문에 비밀번호가 안전하게 보호가 가능합니다.
    사용자가 비밀번호를 입력하면 비밀번호를 해싱하고, 서버에 있는 해시랑 비교하며 사용자의 신원을 확인합니다.

  • 해시 테이블
    테이블의 인덱스로 해시를 사용하는 자료구조입니다.
    검색이 빠르다는 장점이 있지만 충돌이 일어날 수 있다는 위험이 있습니다.

✅ 복호화(Decryption)

복호화는 암호화의 기본 요소입니다.
신시웨이 암호화 복호화[출처 | 신시웨이]
암호화 알고리즘을 사용하여 평문을 암호문으로 변환합니다.

이후 암호화된 데이터를 원래의 원본 데이터로 되돌리는 과정으로 암호문과 암호키를 사용하여 수행됩니다.

이과정을 복호화라하며 올바른 암호키를 사용하여 복호화를 수행하여야 암호문이 원본 데이터로 해독 할 수 있습니다.

이제 bcrypt를 알아보자 ⚡️

✅ bcrypt

• 암호화 라이브러리
• 비밀번호를 안전하게 해시(hash) 처리하여 데이터베이스에 저장할 때 사용
• 해싱된 값은 복호화 불가능하고, 비교를 통해 비밀번호를 검증

✅ 주요기능

✔️ 비밀번호 해싱

  • 비밀 번호를 안전하게 암호화함
    해당 코드와 같이 해쉬 가능
// 내가 삽입한 password를 해쉬함 | 작업 계수 10 (2^10 = 1,024회 반복)
bcrypt.hash(password, 10, (err, hash) => {
      if (err) {
        console.error('해싱 에러:', err);
        return res.status(500).send('Server error occurred while hashing.');
      }
      console.log('해싱된 비밀번호:', hash);
  • BCrypt는 '작업 계수(work factor)'라는 매개변수를 사용합니다.
  • 이 작업 계수는 해시를 생성하는 데 필요한 계산 횟수를 결정합니다.
  • 계수가 1 증가할 때마다 필요한 계산 시간은 2배로 증가합니다.
// 작업 계수 10 (2^10 = 1,024회 반복)
bcrypt.hashpw(password, bcrypt.gensalt(10))

// 작업 계수 12 (2^12 = 4,096회 반복)
bcrypt.hashpw(password, bcrypt.gensalt(12))

✔️ 해시 비교

  • 입력된 비밀번호와 저장된 해시를 비교
    해당 코드와 같이 비교 가능
// password와 hashed password를 compare 함수를 통해 비교해 맞는지 비교 확인한다.
bcrypt.compare(password, hashedPassword, (err, result) => {
        if (err) {
          console.error('비교 에러:', err);
          return res.status(500).send('Server error occurred while comparing passwords.');
        }
        console.log('비밀번호 일치 여부:', result);

✔️ 솔트(salt)

  • 동일한 비밀번호에 대해 서로 다른 해시 값을 생성하기 위해 랜덤 데이터를 추가한다. 솔트가 있기에 같은 비밀번호일지라도 다른 해시 값을 가지게된다.
    [출처 | velog_sangmin7648]

✅ bcrypt 해쉬 비밀번호 구조

[출처 | velog_sangmin7648]
✔️ Algorithm
• 알고리즘 식별자. '2a2a$'는bcrypt를 의미
✔️ Cost factor
• 키 스트레칭한 횟수. 2^n으로 위의 경우 2^10=1024
✔️ Salt
• 128비트 솔트, 22자 base64로 인코딩
✔️ Hash
• salting과 키 스트레칭 후 해시 값
✔️ bcrypt에서 검증
• 비밀번호가 동일한지 검증하기 위해 입력된 비밀번호에 salting, 키 스트레칭을 해서 저장된 bcrypt 문자열과 비교

✅ 장점

✔️ 복호화 불가능

  • 해시된 비밀번호는 복호화할 수 없음
    ✔️ 솔트(salt)로 안전성 강화
  • 동일한 비밀번호에 대해 다른 해시 값을 생성함
    ✔️ 간단한 사용
  • 비밀번호 저장 및 비교를 간편하게 처리 가능

✅ 단점

✔️ CPU사용 량

  • 솔트 라운드 수가 높을수록 처리 시간이 길어진다.
    * 상단 코드에서 보았던 해당 부분에서 10을 나타낸다.
bcrypt.hash(password, 10, (err, hash) => {...

✅ 주의사항

  • 비밀번호는 절대 평문으로 저장하면안된다.(반드시 해쉬 비밀번호로 저장)
  • 솔트 라운드 값을 적절히 설정(10~12추천)
  • bcrypt는 비밀번호 해싱 전용이며, 데이터 암호화에는 사용하지 않음

오늘은 bcryp에 대해 알아보았습니다. 감사합니다.

출처

토스페이먼츠 개발자 센터, MDN, 업비트 투자자보호센터

메모 오류 해결 list

[2019.06.04] 오늘의 TIL- 암호화 bcrypt.compare가 무조건 false로 나던 문제

profile
'같이의 가치를'

0개의 댓글