암호화

sese·2022년 10월 14일

새싹

목록 보기
26/39

[ 암호화 종류 ]

  • 단방향 암호화 (복호화 불가)
  • 양방향 암호화

[ 해시 (Hash) ]

  • 단방향 암호화의 암호화 방식 중 하나
  • 해시 함수 (Hash Function) = 해시 알고리즘
    - 키 (key) : 매핑 전 원래 데이터 값
    - 해시 값 (hash value) : 매핑 후 데이터 값
    - 해싱 (hashing) : 매핑하는 과정

[ bcrypt ]

  • 암호화 알고리즘
  • Blowfish 암호를 기반으로 설계된 암호화 함수
  • 현재까지도 사용중인 가장 강력한 매커니즘임과 동시에 해싱이 느리고 비
    용이 많이 든다.
  • 강력한 보안이 필요할 때 적합

[ 암호화 보완법 ]

  • salt : 입력한 값에 salt 라는 특정 값을 붙여 변형시키는 것 (소금을 치는 것과 비슷하다고 그래서 salt 라고 부름)
  • 해시 함수 반복 : 해시 함수를 여러 번 돌려 본래의 값을 예측하기 어렵게 만드는 것

[ 레인보우 테이블 ]

  • 해시 함수를 사용해 만들어낼 수 있는 값들을 대량으로 저장해놓은 표
  • 즉, 보통 해시함수를 이용해 저장된 비밀번호로부터 원래의 비밀번호를 추출해내는데 사용된다.

[ crypto ]

  • 암호화 알고리즘이 모여 있는 패키지

[ crypto 검증 ]

  • crypto 는 단방향 알고리즘이기 때문에 복호화가 불가능
  • 즉, 입력한 값과 동일한 알고리즘을 이용해 다시 암호화를 해 비교한다.
  • 이 때 같은 salt 값을 사용하여야 하므로 데이터베이스에 salt 값도 저장해주어야 한다.

[ 실습 - crypto ]

crypto 설치

$ npm i crypto

MVC - Controller

const models = require("../model");
// crypto 모듈 가져오기
const crypto = require('crypto');

exports.main = (req, res) => {
    res.render("index");
}

exports.register = async (req,res) => {
	
  	// 해시 알고리즘
    const createHashedPassword = (password) => {
        //randomBytes(64) : 64바이트 길이로 salt를 생성한다.
        const salt = crypto.randomBytes(64).toString('base64');
        //pbkdf2sync(해시할 값, salt, 해시 함수 반복 횟수, 해시 값 길이, 해시 알고리즘)
        const hashed = crypto.pbkdf2Sync(password, salt, 10, 64, 'sha512').toString('base64');
        // 해시 값(암호화된 비밀번호)과 salt를 반환한다 
        return {hashed, salt};
    }

    // 해시 값 : hashed.hashed, salt : hashed.salt
    let hashed = createHashedPassword(req.body.pw);
    let hashedPassword = hashed.hashed;
    let salt = hashed.salt;
	
    // 데이터베이스에 아이디, 해시 값, salt를 삽입한다.
    let obj = {
        id : req.body.id,
        password: hashedPassword,
        salt: salt
    }
    let result = await models.User.create(obj);
    res.render("login");
}

exports.loginPage = (req, res) => {
    res.render("login");
}

exports.postLogin = async (req, res) => {
    // id로 salt값을 가져온다 (아이디 중복 불가)
    let salt_result = await models.User.findOne({where: {id : req.body.id}});
    // 가져온 salt 값과 위에서 사용한 해시 알고리즘을 사용하여 재암호화 한다.
    const verifyPassword = (password, salt) => {
        const hashed = crypto.pbkdf2Sync(password, salt, 10, 64, 'sha512').toString('base64');
        return hashed;
    }
    // 해시 값
    let hashedPassword = verifyPassword(req.body.pw, salt_result.salt);
    // 데이터베이스에 저장되어 있는 해당 id의 암호화된 비밀번호와 방금 얻은 해시값을 비교한다
    if ( salt_result.password === hashedPassword ) {
        res.send("로그인 성공");
    } else {
        res.send("로그인 실패");
    }
}

[ 실습 - bcryptjs ]

bcryptjs 설치

$ npm i bcryptjs

MVC - Controller

const models = require("../model");
// bcrypt 모듈 가져오기
const bcrypt = require("bcryptjs");

exports.main = (req, res) => {
    res.render("index");
}

exports.register = async (req,res) => {
  
	// 암호화 알고리즘
    const doBcrypt = (password) => {
        const salt = bcrypt.genSaltSync(10);
        const hash = bcrypt.hashSync(password, salt);
        return hash
    }
	
    // 해시 값
    let bcrypted = doBcrypt(req.body.pw);

    let obj = {
        id : req.body.id,
        password: bcrypted
    }
    
    let result = await models.User.create(obj);
    res.render("login");
}

exports.loginPage = (req, res) => {
    res.render("login");
}

exports.postLogin = async (req, res) => {
    // 아이디로 검색한 사용자 정보
    let result = await models.User.findOne({where: {id : req.body.id}});
  	
  	// bcrypt.compare(입력된 비밀번호, 암호화 된 비밀번호)
    let verify_result = await bcrypt.compare(req.body.pw, result.password);

    if (verify_result) {
        res.send("로그인 성공");
    } else {
        res.send("로그인 실패");
    }
}
profile
예전 글은 다크모드로 봐야 잘 보일 수도 있습니다.

0개의 댓글