개발 도중 crypto라는 모듈을 사용해서 비밀번호를 암호화를 진행하였습니다. 그런데 그냥 모듈을 사용하는 것보다 어떤 방식으로 비밀번호가 암호화되는지 궁금하여 찾아본 결과, 관련된 Hash를 정리하고자 합니다.

해시(Hash)란?

다양한 길이를 가진 데이터를 고정된 길이를 가진 데이터로 매핑(mapping)한 값입니다. 이를 이용해 특정한 배열의 인덱스나 위치나 위치를 입력하고자 하는 데이터의 값을 이용해 저장하거나 찾을 수 있습니다. 기존에 사용했던 자료 구조들은 탐색이나 삽입에 선형시간이 걸리기도 했던 것에 비해, 해시를 이용하면 즉시 저장하거나 찾고자 하는 위치를 참조할 수 있으므로 더욱 빠른 속도로 처리할 수 있습니다.

해시함수란?

해시 함수는 임의의 길이를 갖는 임의의 데이터에 대해 고정된 길이의 데이터로 매핑하는 함수를 말합니다. 이러한 해시 함수를 적용하여 나온 고정된 길이의 값을 해시값이라고 합니다. 보통 그리 복잡하지 않은 알고리즘으로 구현되기 때문에, 상대적으로 CPU, 메모리 같은 시스템 자원을 덜 소모하는 특성이 있습니다. 그리고 해시 함수는 결정록적으로 작동하기 때문에, 원래의 데이터가 같으면 해시값도 항상 동일하며, 이 출력값은 가능한 한 고른 범위에 균일하게 분포하는 특성이 있습니다. 특수 목적용으로 해시값을 생성하는 원본과 별도의 값을 받아서 같은 입력에 대해 다른 출력값을 가지게 하는 해시 함수도 존재한다.

* 밑줄 : A라는 사람이 'abc'를 입력하여 해시함수를 통해 매핑을 해서 나온 결과 값은 B라는 사람이 'abc'를 입력하여 해시함수를 통해 매핑해서 나온 결과 값과 같다. 

해시함수는 어떻게 활용될까요?

자료구조, 캐시, 중복 레코드 검색, 유사 레코드 검색, 에러검출 등 다양한 분야에서 유용하게 사용됩니다.
대표적인 해시 함수 : MD5, SHA

해시 테이블이란?

해시 테이블은 키와 값을 매핑해 둔 데이터 구조입니다. 해시함수를 이용하여 검색하고자 하는 값을 반환하면 그 값이 저장된 위치를 즉시 알아낼 수 있습니다. 데이터의 양이 아무리 많아지더라도 원리적으로 해시 변환과 검색에 걸리는 시간은 항상 동일합니다. 따라서 방대한 데이터에서 특정한 값을 검색할 때 해시 테이블을 사용하면 검색 시간을 획기적으로 단축할 수 있습니다.
*해시 맵(hash map)은 기존 해시 테이블의 기능을 개선한 신 버전의 해시 테이블입니다.

해싱

해싱이란 해시함수를 사용하여 주어진 값을 변환한 뒤, 해시 테이블에 저장하고 검색하는 기법을 말합니다. 해싱에 사용되는 자료구조는 배열(array)와 연결리스트(linked list)가 조합된 형태입니다. 짧은 해시 키를 사용하여 항목을 찾으면, 원래의 값을 이용하여 찾는 것보다 더 빠르기 때문에, 해싱은 데이터베이스 내의 항목들을 색인하고 검색하는 데 사용된다. 

해시는 어디서 활용이 되나요?

해시는 블록체인과 IPFS 등 다양한 분야에서 활용되고 있습니다. 보안 분야에서도 널리 사용되는데 이는 해시 함수가 원래의 문장을 복호화할 수 없게 뭉개버린다는 장점과 원문과 해시값 사이에 선형적 관계가 없다는 특성을 지니고 있기 때문입니다.

Node에서 사용되는 예제

const crypto = require('crypto');
const util = require('util');

const pbkdf2Promise = util.promisify(crypto.pbkdf2);
const randomBytesPromise = util.promisify(crypto.randomBytes);

module.exports = {
	
    /**
     * Create HashedPassword
     * @param {String} password 
     * @returns String, String
     */
    createHashedPassword: async (password, currnet_salt) => {
        const salt = currnet_salt;
        const key = await pbkdf2Promise(password, salt, Number(process.env.KEY_STRETCHING), 64, "sha512");
        const hashedPassword = key.toString("base64");
        return { hashedPassword, salt };
    },

    /**
    * verifyPassword
    * @param {String} password 
    * @param {String} userSalt 
    * @param {String} userPassword 
    * @returns boolean
    */
    verifyPassword: async (password, userSalt, userPassword) => {
        const key = await pbkdf2Promise(password, userSalt, Number(process.env.KEY_STRETCHING), 64, 'sha512');
        const hashedPassword = key.toString('base64');
        if (hashedPassword === userPassword) return true;
        return false;
    }
}

참고 자료 : http://wiki.hash.kr/index.php/%ED%95%B4%EC%8B%9C

'CS(Computer science) > 자료구조' 카테고리의 다른 글

Stack/Queue 이란?  (2) 2023.04.20

Stack(스택) 이란?

제한적으로 접근할 수 있는 나열 구조이며, 접근 방법은 언제나 목록의 끝에서만 일어납니다. 끝먼저내기 목록이라고도 합니다.

스택은 한 쪽 끝에서만 자료를 넣거나 뺄 수 있는 선형 구조(LIFO - Last in Firsh Out)으로 되어 있습니다. 자료를 넣는 것을 '밀어넣는다' 하여 푸쉬(Push)라고 하고 반대로 넣어둔 자료를 꺼내는 것을 팝(pop)이라고 하는데, 이때 꺼내지는 자료는 가장 최근에 푸쉬한 자료부터 나오게 됩니다. 이처럼 나중에 넣은 값이 먼저 나오는 것을 LIFO구조 라고 합니다.

나무위키에서 가져온 스택의 구조

그렇다면 이 스택은 어디에 활용이 될까요?

- 웹 브라우저 뒤로가지 : 가장 나중에 열린 페이지부터 뒤로 가기.
- 문서작업에서 Ctrl + Z : 가장 나중에 수정한 내용을 되돌림.
- 재귀적 알고리즘
- 후위 표기법 계산 등등


큐(Queue)란?

스택과 반대로 먼저 집어 넣은 데이터가 먼저 나오는 FIFO(First In First Out) 구조로 저장하는 형식을 말합니다.
영어 단어의 queue는 표를 사러 일렬로 늘어선 사람들로 이루어진 줄을 말하기도 하며, 먼저 줄을 선 사람이 먼저 나갈 수 있는 상황을 연상하면 됩니다.
큐는 put(insert) get(delete)을 이용하여 구현된다. put는 큐에 자료를 넣는것, get은 큐에서 자료를 꺼내는 것을 의미합니다. front(head)와 rear(tail)는 데이터의 위치를 가르킨다. 종류에는 선형과 환영이 있습니다.

나무위키에서 가져온 큐의 구조

그렇다면 이 큐는 어디에 활용이 될까요?

- 프린터의 출력 처리
- 윈도 시스템의 메시지 처리기
- 프로세스 관리 등 데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황

오버플로(Overflow)와 언더플로(Underflow)란?

  1. 오버플로는 특정한 자료구조가 수용할 수 있는 데이터의 크기를 이미 가득 찬 상태에서 삽입 연산을 수행할 때 발생합니다.
  2. 언더플로는 특정한 자료구조에 데이터가 전혀 들어 있지 않은 상태에서 삭제 연산을 수행할 때 발생합니다.


Node의 구조 및 동작 원리를 살펴보면 이 안에서도 사용이 됩니다.
예를 들어, 테스크 큐(Task Queue)나 콜스택(Call Stack)처럼 코드가 어떻게 동작하는지 관련해서 알고가는 것이 좋다고 생각하여 정리하게 되었습니다.

 

참고 : https://ko.wikipedia.org/wiki/%EC%8A%A4%ED%83%9D

 

스택 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 스택(stack)은 제한적으로 접근할 수 있는 나열 구조이다. 그 접근 방법은 언제나 목록의 끝에서만 일어난다. 끝먼저내기 목록(Pushdown list)이라고도 한다. 스택은

ko.wikipedia.org

https://ko.wikipedia.org/wiki/%ED%81%90_(%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0)

'CS(Computer science) > 자료구조' 카테고리의 다른 글

Hash란?  (0) 2023.04.20

+ Recent posts