암호화의 종류는 두 가지가 있는데 아래와 같다.
- 양방향 암호화 : 암호화와 복호화 과정을 통해 송,수신 간 주고받는 메세지를 안전하게 암호화한 후 평문으로 복호화를 하는 과정
- 단뱡향 암호화 : hashing 을 이용한 암호화 방식으로서, 평문을 암호문으로 암호화가 가능하지만, 암호문을 평문으로 다시 복호화 하는 것은 불가능하다.
양방향 암호화는 암호문을 평문으로 복호화 가능하기 때문에 보통 단방향 암호화를 이용하는 편이다.
<단방향 해시 함수의 종류>
- SHA
- MD
- HAS
- WHIRLPOOL
이렇게 4 종류 중에 대표적으로 SHA-256 알고리즘이 많이 사용된다.
<Key Stretching >
단순 해시 함수를 이용하여 변환만 한다면 보안이 완벽하다고 할 수 없다. 왜냐하면 해커들이 레인보우 테이블을 이용하여 엄청난 경우의 수의 복호화를 대입해 볼 수 있기 때문이다. 이 때, 보안을 좀 더 철저히 하기 위해 생겨난 방법이 키-스트레칭 이다.
키-스트레칭은 개발자가 횟수를 정하여 해시함수를 돌리는 방법으로서, 비밀번호를 저장할 때 가장 쉽게 생각할 수 있는 방법이다.
<Salt>
키-스트레칭은 만약, 해커들이 돌린 횟수만 알게 된다면 언제든지 보안이 뚫릴 수 있는 단점이 있는데, Salt는 해당 암호화된 문자에 임의의 문자열을 덧붙이기 때문에 좀 더 보안이 뛰어나다. 그리고, 사용자마다 다른 Salt를 사용한다면 Digest 값이 달라지기 때문에, 어떤 임의의 사용자의 비밀번호가 유출되더라도 해당 사용자와 똑같은 비밀번호를 사용하는 다른 사용자의 비밀번호는 비교적 안전할 수 있다.
<NestJS - Bcrypt>
1. Nestjs 에서 암호화를 하기 위해 bcrypt 라는 모듈을 설치해주자.
$ npm install bcrypt
$ npm install @types/bcrypt // 타입스크립트에서 제공하는 모듈
2. gql 을 사용하는 분들은 user.resolver.ts 에 아래의 코드를 대입한다.
// user.resolver.ts
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { User } from './entities/user.entity';
import { UserService } from './user.service';
import * as bcrypt from 'bcrypt';
@Resolver()
export class UserResolver {
constructor(
private readonly userService: UserService, //
) {}
@Mutation(() => User)
async createUser(
@Args('email') email: string,
@Args('password') password: string,
@Args('name') name: string,
@Args('age') age: number,
) {
const stufithashpassword = await bcrypt.hash(password, 10);
console.log(hashedPassword);
return this.userService.create({ email, stufithashpassword, name, age });
}
}
// 1. 설치한 bcrypt 모듈을 불러온다.
// 2. 21번째 줄에서 hash 알고리즘을 이용하는데, hash 메서드의 첫번째 인자는 사용자가 입력한 비밀번호이다.
// 3. 두번째 인자는 Salt 이므로, 10 의 의미는 password 를 10 회 Salt 시켜준다는 의미이다.
3. user.service 에서 password 를 repository 로 보내어 저장한다.
// user.service.ts
import { ConflictException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
// 파라미터 stufithashpassword 는 changedpassword 로 name을 변경할 수 있다.
async create({ email, stufithashpassword: changedpassword, name, age }) {
const user = await this.userRepository.findOne({ email });
if (user) throw new ConflictException('이미 등록된 이메일 입니다.');
// password 는 DB에 password 라는 컬럼으로 되어 있으므로, password는 changedpassword 라는 뜻이다.
return await this.userRepository.save({ email, password:changedpassword, name, age });
}
}
4. gql 호출
: createUser 로 계정 생성 시, 다음과 같이 response 를 받는다.
5. DB 확인
: password 부분이 해쉬암호화 된 것이 확인된다.
'백엔드 > NestJs' 카테고리의 다른 글
필수 패키지 설치 (0) | 2023.05.02 |
---|---|
[nestjs] 미들웨어에서 method 지정 코드 (0) | 2023.03.21 |
nestjs elasticsearch module set up (0) | 2022.08.22 |
Validation 설정 (0) | 2022.08.01 |
useGlobalPipes 선언을 통한 @Param 타입변환 및 Validation (0) | 2022.08.01 |