NestJS 게시글 본문 AES 암복호화, CORS 허용

박재하·2023년 11월 24일
0

목표

  • 게시글 본문 암복호화
  • CORS 허용

게시글 본문 암복호화

AES 암복호화 모듈

스프린트때 직접 개발해두었던 암복호화 모듈을 활용해 utils에 넣었다. (학습메모 1)

// aes.util.ts
import crypto from 'crypto';
import { aesConfig } from '../config/aes.config';

const encryptAes = (plainText) => {
	const algorithm = 'aes-256-cbc'; // 암호 알고리즘
	const key = crypto.scryptSync(aesConfig.password, aesConfig.salt, 32); // 암호화 키
	const iv = aesConfig.iv; // 초기화 벡터

	const cipher = crypto.createCipheriv(algorithm, key, iv);
	let cipherText = cipher.update(plainText, 'utf8', 'base64');
	cipherText += cipher.final('base64');
	return cipherText;
};

const decryptAes = (cipherText) => {
	const algorithm = 'aes-256-cbc'; // 암호 알고리즘
	const key = crypto.scryptSync(aesConfig.password, aesConfig.salt, 32); // 암호화 키
	const iv = aesConfig.iv; // 초기화 벡터

	const decipher = crypto.createDecipheriv(algorithm, key, iv);
	let plainText = decipher.update(cipherText, 'base64', 'utf8');
	plainText += decipher.final('utf8');
	return plainText;
};

export { encryptAes, decryptAes };
import { configDotenv } from 'dotenv';
configDotenv();

export const aesConfig = {
	password: process.env.AES_PASSWORD,
	salt: process.env.AES_SALT,
	iv: Buffer.alloc(16, 0),
};

config 파일로 .env에 있는 AES_PASSWORD, AES_SALT를 활용하도록 보안처리

적용

이제 POST /board, PATCH /board/:idGET /board에 암복호화 처리를 넣어준다.

// board.service.ts
...
import { encryptAes, decryptAes } from 'src/utils/aes.util';

@Injectable()
export class BoardService {
	...

	async createBoard(createBoardDto: CreateBoardDto): Promise<Board> {
		const { title, content, author } = createBoardDto;

		const board = this.boardRepository.create({
			title,
			content: encryptAes(content), // AES 암호화하여 저장
			author,
		});
		const created: Board = await this.boardRepository.save(board);

		return created;
	}

	async findBoardById(id: number): Promise<Board> {
		const found: Board = await this.boardRepository.findOneBy({ id });
		if (!found) {
			throw new NotFoundException(`Not found board with id: ${id}`);
		}
		if (found.content) {
			found.content = decryptAes(found.content); // AES 복호화하여 반환
		}
		return found;
	}

	async updateBoard(id: number, updateBoardDto: UpdateBoardDto) {
		const board: Board = await this.findBoardById(id);

		// updateBoardDto.content가 존재하면 AES 암호화하여 저장
		if (updateBoardDto.content) {
			updateBoardDto.content = encryptAes(updateBoardDto.content);
		}

		const updatedBoard: Board = await this.boardRepository.save({
			...board,
			...updateBoardDto,
		});
		return updatedBoard;
	}
}

결과 화면

스크린샷 2023-11-22 오후 12 03 14

암호화돼서 잘 저장됨

스크린샷 2023-11-22 오후 12 03 37

GET으로 요청할 땐 복호화되어 반환됨

스크린샷 2023-11-22 오후 12 05 11

DB에 저장될때는 암호문으로! IV나 salt를 컬럼에 있는 값을 조합해서 쓰면 같은 input이라도 다른 암호문이 나오게 할 수 있다. 필요하면 개선하자

CORS 허용

프론트 분들의 API 테스트를 위해 배포중인 테스트 서버에서 CORS 허용이 필요했다.

localhost에서 띄운 프론트 서버에서 테스트 API서버에 접근할 수 있게 다음과 같이 설정해주면 된다.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import * as cookieParser from 'cookie-parser';

async function bootstrap() {
	const app = await NestFactory.create(AppModule);

	app.use(cookieParser());

	// cors 허용
	app.enableCors({
		origin: true,
		credentials: true,
	});

	const config = new DocumentBuilder()
		.setTitle('B1G1 API')
		.setDescription('B1G1 API description')
		.setVersion('1.0')
		.addTag('b1g1')
		.build();
	const document = SwaggerModule.createDocument(app, config);
	SwaggerModule.setup('api', app, document);

	await app.listen(3000);
}
bootstrap();

학습메모

  1. AES 암복호화
  2. CORS 허용
profile
해커 출신 개발자

0개의 댓글