[Research] bcrypt vs bcryptjs

gimseonjin616·2022년 2월 16일
3

Research

목록 보기
5/8

들어가며

요즘 Springboot Security의 로직을 공부하면서 node js의 Spring이라고 불리는 nest js에 대해 같이 공부하고 있다.

그러면서 유저 인증 관련 로직을 구현하면서 bcryptjs라는 라이브러리를 알게되었다.

bcryptjs는 bcrypt 라이브러리를 js에서 사용할 수 있도록 구현되서 nest js에선 무조건 bcryptjs를 사용해야 하는 줄 알았으나 최근에 nest js에서도 bcrypt 라이브러리를 사용할 수 있다는 것을 발견했다.

그렇다면 bcrypt 라이브러리가 있는데 왜 bcryptjs가 생겨났는 지, 두 라이브러리를 비교해보기로 했다.


npm 내부 사용 빈도

bcrypt

bcryptjs

두 라이브러리의 사용 빈도를 비교해보면 bcryptjs가 bcrypt에 비해 약 1.43배 많이 사용되었다.


성능 비교

두 라이브러리를 통해 10개의 임의 비밀번호를 암호화하고 기존 비밀번호와 비교하는 로직의 처리 시간을 비교해보고자 한다.

구현하는 로직은 다음과 같다.

  • Async 기반의 암호화 로직
  • Async 기반의 암호 비교 로직
  • Sync 기반의 암호화 로직
  • Sync 기반의 암호 비교 로직

bcrypt Code

// bcrypt library

import bcrypt from 'bcrypt';

const password = [  'MyPassword123!@#',
                'YourPassword123!@#',
                'MyPassword456!@#',
                'YourPassword**123!@#',
                'MyPass123!@#!@#',
                'Password123!@@@@#',
                'mypassword!!@#',
                'MyPassword!@#',
                'MyPassword123123',
                'MyPas(!)@#*!@)'  ]


async function doTest (password, i) {

    const saltRounds = 8;
    
    var hashAsync;
    var hashSync;

    console.log(`State : ${i}, Password : ${password} `)
	
    // - Async 기반의 암호화 로직
    console.time('bcrypt_Async Generate Hash');
    hashAsync = await bcrypt.hash(password, saltRounds);
    console.timeEnd('bcrypt_Async Generate Hash');

	// - Async 기반의 암호 비교 로직
    console.time('bcrypt_Async Compare Hash');
    await bcrypt.compare(password, hashAsync)
    console.timeEnd('bcrypt_Async Compare Hash');

	// - Sync 기반의 암호화 로직
    console.time('bcrypt_Sync Generate Hash');
    hashSync = bcrypt.hashSync(password, saltRounds);
    console.timeEnd('bcrypt_Sync Generate Hash')

	// - Sync 기반의 암호 비교 로직
    console.time('bcrypt_Sync Compare Hash');
    bcrypt.compareSync(password, hashSync);
    console.timeEnd('bcrypt_Sync Compare Hash');

    console.log();
}


for (var i = 0; i < 10; i++) {
    await doTest(password[i], i);
}

bcryptjs Code

// bcryptjs library

import bcryptjs from 'bcryptjs';

const password = [  'MyPassword123!@#',
                'YourPassword123!@#',
                'MyPassword456!@#',
                'YourPassword**123!@#',
                'MyPass123!@#!@#',
                'Password123!@@@@#',
                'mypassword!!@#',
                'MyPassword!@#',
                'MyPassword123123',
                'MyPas(!)@#*!@)'  ]


async function doTest (password, i) {

    const saltRounds = 8;
    
    var hashAsync;
    var hashSync;

    console.log(`State : ${i}, Password : ${password} `)

    // - Async 기반의 암호화 로직
    console.time('bcryptjs_Async Generate Hash');
    hashAsync = await bcryptjs.hash(password, saltRounds);
    console.timeEnd('bcryptjs_Async Generate Hash');

	// - Async 기반의 암호 비교 로직
    console.time('bcryptjs_Async Compare Hash');
    await bcryptjs.compare(password, hashAsync)
    console.timeEnd('bcryptjs_Async Compare Hash');

	// - Sync 기반의 암호화 로직
    console.time('bcryptjs_Sync Generate Hash');
    hashSync = bcryptjs.hashSync(password, saltRounds);
    console.timeEnd('bcryptjs_Sync Generate Hash')

	// - Sync 기반의 암호 비교 로직
    console.time('bcryptjs_Sync Compare Hash');
    bcryptjs.compareSync(password, hashSync);
    console.timeEnd('bcryptjs_Sync Compare Hash');

    console.log();
}



for (var i = 0; i < 10; i++) {
    await doTest(password[i], i);
}

실행 결과

bcrypt

bcryptjs

평균 수행 시간 비교

평균적으로 4개의 로직 모두에서 bcryptjs 라이브러리가 bcrypt 라이브러리에 비해 약 1.5배의 시간이 더 소요되는 것을 알 수 있다.


bcrypt 라이브러리의 제작자, kelektiv의 코멘트

bcrypt github 위키에 보면 제작자 kelektiv가 남긴 코멘트를 볼 수 있다.

위 코멘트를 해석하면 다음과 같다.

'bcryptjs 라이브러리는 순수 자바스크립트로 구현된 라이브러리로 c++로 구현된 bcrypt 라이브러리를 코드의 변화없이 대체할 수 있다.

다만 c++로 구현되어 스레드 풀 방식을 사용하는 기존의 bcrypt 라이브러리에 비해 단일 스레드로 구성된 js로 구현된 bcryptjs 라이브러리가 약 30%의 성능 차이를 보인다.

그러나 브라우저에서는 bcrypt 라이브러리가 동작하지 않기 때문에 웹브라우저 환경에서는 bcryptjs 라이브러리가 유일한 선택지다.'


결론

bcrypt 라이브러리가 bcryptjs 라이브러리에 비해 약 30% 정도 성능적으로 우수하지만 웹브라우저 환경에서 사용할 수 있다는 장점으로 인해 bcryptjs 라이브러리가 더욱 많이 사용된다.

profile
to be data engineer

0개의 댓글