-
[NestJS] 랜덤 문자열을 생성하여 양방향 암호화 진행하기공부/Nest 2024. 4. 23. 00:57
회사에서 기능구현을 하는 부분에서 양방향 암호화가 필요한 부분이 있었습니다. 이번에는 블로그에 회사에서 경험했던 일을 위주로 암호화에 대해서 랜덤문자열을 생성하는 방식과 함께 설명하려고 합니다.
양방향 암호화란?
암호화된 암호문을 복호화할 수 있도록 암호화하는 방법을 양방향 암호화라고 합니다.
key를 이용해서 암호화와 복호화를 진행하지만 key를 어떻게 사용하느냐에 따라서 공개키, 비공개키 방식으로 나눌 수 있습니다.
- 비공개키는 대칭키라고도 하며 하나의 키로 암호화, 복호화를 진행합니다.
- 공개키는 비대칭키라고도 하며 서로 다른 키를 이용합니다.
오늘 이야기할 부분은 양방향 암호화에서 비공개키(대칭키) 방식을 이용하여 설명하려고 합니다.
NestJS의 내장 모듈 crypto를 이용한 양방향 암호화
NestJS에 내장된 모듈 crypto를 이용하면 쉽게 양방향 암호화를 진행할 수 있습니다.
# 암호화 import { createCipheriv, createDecipheriv } from 'crypto'; async encrypt(data: string) { /** * const stringIv = randomBytes(16); - 16바이트의 난수를 생성하고, 16진수(0~F으로 표현) 문자열로 변환 * const iv = Buffer.from(stringIv, 'hex'); - 다시 16진수로 변환, IV는 암호화 및 복호화 과정에서 사용 * const bufferKey = (await promisify(scrypt)('Text', 'salt', 32)) as Buffer; - scrypt 함수를 사용하여 Text와 salt를 이용하여 32바이트 길이의 키를 생성 */ const cipher = createCipheriv(this.algorithm, iv, bufferKey); return cipher.update(data, 'utf8', 'hex') + cipher.final('hex'); }저의 경우에는 대칭키 방식으로 암호화를 하기때문에, 생성한 키와 IV를 노출하지 않도록 관리하고 있습니다.
여기서 'hex'는 16진수(hexadecimal)의 약자이며, 인코딩 형태를 지정하기 위해서 사용하였습니다.
알고리즘은 'AES-256-CTR' , 'AES-256-CBC' 2가지 방법이 있으나, 공식문서에서 AES-256-CTR를 이야기하고 있습니다.
- 2개의 차이는 암호화 방식과 생성에서 차이가 있지만 2가지 중 어떤 것을 사용해도 괜찮은 거 같습니다.
# 복호화 async decrypt(data:string){ const decipher = createDecipheriv(this.algorithm, bufferKey, bufferIv); const decrypted = decipher.update(accessSecret, 'hex', 'utf8') + decipher.final('utf8'); return decrypted }buffetKey, bufferIV는 암호화에서 사용했던 Key, IV를 사용하였습니다.
복호화에서는 input 값은 hex로 인코딩했기때문에 'hex'로 입력을 하고, output은 'utf8'로 인코딩하였습니다.
여기서 중점으로 생각해야 하는 부분이 createDecipheriv, createCipheriv에 전달하는 파라미터의 값들 중 iv, key는 buffer 형태로 전달이 돼야 합니다.
랜덤 문자열 생성하기
function createRandomString() { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let result = ""; let num = 10; for (let i = 0; i < num; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; }chars는 가상의 문자를 나열해 놓은 것입니다.
반복문을 통해 랜덤으로 문자열의 값을 result에 추가하는 방식으로 num으로 원하는 랜덤 string의 값을 길이를 설정할 수 있습니다.
저의 경우 랜덤 문자열을 생성, 특정 문자열과 합친 후 양방향 암호화를 이용해야 하는 부분이 있어서 함께 사용하였습니다.
암호화라는 부분은 현재 사용하기 편한 라이브러리와 모듈들이 많지만 전문적인 지식이 필요하다고 생각합니다.
Ref.
https://docs.nestjs.com/security/encryption-and-hashing
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
https://junu128.tistory.com/52
2-9. 노드 crypto(암호화) 와 util
I. 단방향 암호화 (crypto) 1. 암호화는 가능하지만 복호화는 불가능 - 암호화 : 평문을 암호로 만듦 - 복호화 : 암호를 평문으로 만듦 2. 단방향 암호화의 대표 주자는 해시 기법 - 문자열을 고정된
junu128.tistory.com
https://sentry.io/answers/generate-random-string-characters-in-javascript/
Generate random string/characters in JavaScript
The Problem You want to generate a random string of characters in JavaScript. There are many use cases for this, including: Create unique IDs. Generate test…
sentry.io
검색하며 찾아보고 작성한 글입니다. 혹시라도 부정확한 정보를 전달드릴 수 있습니다. 틀린 부분이 있으면 댓글을 남겨주세요.
'공부 > Nest' 카테고리의 다른 글
ReferenceError: crypto is not defined (0) 2025.05.24 [Nest] CPU 상승 개선을 위한 Docker로 Redis 적용 (0) 2024.10.06 [Nest] TypeORM의 DELETE, REMOVE 차이 (0) 2024.06.02 [NestJS] 기본 구조 (0) 2023.09.09 Nest 설치 및 Nest 명령어로 실행이 안되는 경우 (0) 2023.07.15