개발 도중 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

+ Recent posts