4. 내장 모듈(2)

Hyun·2023년 4월 28일
0

nodejs

목록 보기
4/19

1. Crypto

  • 다양한 암호화 기능을 제공
  • pw를 암호화 없이 평문 그대로 db에 저장한다면 db 권한이 있는 관리자 혹은 개발자는 누구나 pw를 볼 수 있고, 해킹을 당하면 다 털려서 막대한 피해를 입을 수 있기때문에 반드시 암호화를 해야한다!

암호화에는 2가지 방식가 있는데 이는 추후 다른 포스트에서 알아보겠다.
1) 단방향 암호화
2) 양방향 암호화

const crypto = require("crypto")
crypto.createHash("sha512").update("1234").digest("base64")

createHash : 암호화에 사용할 알고리즘
update : 암호화할 문자열을 전달
digest : 파라미터로 어떤 인코딩 방식으로 암호화된 문자열을 표시할 건지

하지만 해커는 레인보우 테이블을 사용한다.

  • 레인보우 테이블 : 다양한 암호화 결과 값과 암호화 전 원본 값을 테이블로 가지고 있는 것
    해독하는데 시간이 오래 걸리지만. 해킹에 노출되는 것은 피할 수 없다.

그렇다면 어떻게 해야할까?
레인보우 테이블을 이용하더라도 원본 값을 알아내기 어렵게 하기 위해서 salting 암호화 를 사용한다.

  • randomBytes()를 이용해 64바이트 길이의 salt 생성
const createSalt = () => {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(64, (err, buf) => {
      if (err) reject(err)
      resolve(buf.toString("base64"))
    })
  })
}
  • salt를 이용해 비밀번호 암호화, pbkdf2() 함수를 사용하여 파라미터로 암호화할 문자열, salt, 반복횟수, 출력될 바이트 수, 해시 알고리즘 사용
    반환값은 암호화된 값과 salt값을 반환
const createCryptoPassword = async (plainPassword) => {
  const salt = await createSalt()
  return new Promise((resolve, reject)=>{
    crypto.pbkdf2(plainPassword,salt,10000,64,'sha512',(err,key)=>{
      if(err) reject(err)
      resolve({password:key.toString('base64'),salt})
    })
  })
}

이렇게 생성된 암호화된 비밀번호와 salt값을 db에 함께 저장
사용자가 로그인을 시도할 때 입력한 비밀번호와 db에 저장된 salt 값을 시용해서 암호화된 값을 가져오고, 이 값이 db에 저장된 암호화된 비밀번호와 일치하는지를 비교하여 로그인 처리

  • 입력받은 비밀번호와 db에 저장된 salt 값을 파라미터로 전달하여 암호화된 비밀번호 값 가져오기
const getCryptoPassword = (plainPassword, salt) => {
  return new Promise((resolve, reject) => {
    crypto.pbkdf2(plainPassword, salt, 9999, 64, "sha512", (err, key) => {
      if (err) reject(err)
      resolve({ password: key.toString("base64"), salt })
    })
  })
}

2. File System

  • fs 모듈은 파일 읽기, 쓰기, 삭제 그리고 폴더 생성, 삭제 등과 같은 파일 처리와 관련된 작업을 위한 모듈

파일 읽기

  • fs.readFile(path,[options],callback) : 옵션으로 지정한 문자 인코딩을 사용해서 읽은 후 결과를 callback 함수로 전달하는 비동기 함수
fs.readFile("./sample/text.txt", "utf-8", (err, data) => {
  if (err) throw err
  console.log(data)
})
  • fs.readFileSync(path,[options]) : 옵션으로 지정한 문자 인코딩을 이용해서 utf-8 형식으로 읽은 후 결과를 반환
const text = fs.readFileSync("./sample/text.txt", "utf-8")
console.log(text)

파일 쓰기

  • fs.writeFile(path,data,[options],callback) : options 방식으로 data를 쓰고 callback()함수로 결과를 전달하는 비동기 함수
let data = "파일 쓰기 테스트"
fs.writeFile("./sample/text_w.txt", data, "utf-8", (err) => {
  if (err) throw err
  console.log('비동기적 파일 쓰기 완료')
})
  • fs.writeFileSync(path, data,[options]) : options 방식을 사용해서 data를 쓰는 동기 방식 함수
let data = "파일 쓰기 테스트"
fs.writeFileSync('./sample/text_w.txt',data,'utf-8')

파일 감시
1) 대상이 되는 파일의 변경 사항이 발생하면 지정한 콜백 리스너 함수를 실행
2) sql 쿼리문을 관리하는 sql.js 파일에 변경 사항, 쿼리문이 수정되거나 추가되면 이를 감지하고 반영하는 코드

let sql = require("./sql.js")
fs.watchFile(__dirname + "/sql.js", (curr, prev) => {
  // 변경있는지 확인하고 변경 일어나면 콜백 함수 실행
  console.log("sql 변경 시 재시작 없이 반영")
  delete require.cache[require.resolve("./sql.js")] // 캐쉬에 저장된 파일 삭제
  sql = require("./sql.js") // 변경 일어날 때마다 sql.js 재할당
})

0개의 댓글