똑같은 삽질은 2번 하지 말자
(Node.js) password 암호화 모듈 Crypto(crypto.js에 대해) 본문
Cipher : 일반적인 암호화로 평문 -> 암호문 -> 복호문(평문)의 방식으로 암호화하고 복호화 합니다.
즉, 암호화를 하기 위한 Key 를 가지고 암호화하며, 복호화합니다.
Hmac: 암호화를 하면 다시 되돌릴 수 없기 때문에, 암호화 된 암호문 그 자체를 이용합니다. 흔히
웹사이트 가입하면 운영자도 가입정보를 알 수 없다고 하는건 이렇게 Hmac으로 암호화되어서 입니다.
Module 가져 온뒤, 사용해보겠습니다.
1.Cipher 방식을 이용한 암호화
var crypto = require('crypto');
// 암호화
var cipher = crypto.createCipher('aes256','password');
// aes256 방식으로 password(key)로 암호화하겠다.
cipher.update('TestCipher','ascii','hex');
// update('평문(암호화이전의글)','input type','output type');
var cipherd = cipher.final('hex');
// 암호문
//복호화
var decipher = crypto.createDecipher('aes256','password');
decipher.update(cipherd,'hex','ascii');
var decipherd = decipher.final('ascii');
// 암호화 방법의 parameter 방식은 동일함
2.Hmac 방식을 이용한 암호화
UserSchema
.virtual('password')
.set(function (password) {
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
console.log('virtual password 호출됨 : ' + this.hashed_password);
})
.get(function () {
return this._password
});
// 스키마에 모델 인스턴스에서 사용할 수 있는 메소드 추가
// 비밀번호 암호화 메소드
UserSchema.method('encryptPassword', function (plainText, inSalt) {
if (inSalt) {
return crypto.createHmac('sha1', inSalt).update(plainText).digest('hex');
} else {
return crypto.createHmac('sha1', this.salt).update(plainText).digest('hex');
}
});
// salt 값 만들기 메소드
UserSchema.method('makeSalt', function () {
return Math.round((new Date().valueOf() * Math.random())) + '';
});
// 인증 메소드 - 입력된 비밀번호와 비교 (true/false 리턴)
UserSchema.method('authenticate', function (plainText, inSalt, hashed_password) {
// plainText가 사용자가 입력한 password이고 hashed_password가 암호화되서 저장된 hashed_password 이다.
if (inSalt) {
console.log('authenticate 호출됨 : %s -> %s : %s', plainText, this.encryptPassword(plainText, inSalt), hashed_password);
return this.encryptPassword(plainText, inSalt) === hashed_password;
} else {
console.log('authenticate 호출됨 : %s -> %s : %s', plainText, this.encryptPassword(plainText), this.hashed_password);
return this.encryptPassword(plainText) === this.hashed_password;
}
});
virtual 을 이용해서 Hmac 암호화 방식을 사용해 보았습니다.
virtual 은 MongoDB에 저장되지 않는 속성이므로 편하게 set get을 설정 편의를 위해서 사용하는 것 같습니다.
(사실 왜 쓰는지는 모르겠지만, 개인적인 생각으로는 좀더 유연한 Schema가 되기위한 기능이라고 생각합니다..
정해진 컬렉션 속성들로 여러가지 정보를 추출 비교 하기 위해 만들어진..?)
실제로 passport 인증 모듈에서 password 인증할 때 사용해 보았습니다.
module.exports = new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // 이 옵션을 설정하면 아래 콜백 함수의 첫번째로 req 전달
}, function (req, email, password, done) {
console.log('passport의 local-login 호출됨 : ' + email + ', ' + password);
var database = req.app.get('database');
database.UserModel.findOne({
'email': email
}, function (err, user) {
console.log('-----------------로그인----------------- ');
console.dir(user);// 해당 model 정보 출력
if (err) {
return done(err);
}
// 등록된 사용자가 없는경우
if (!user) {
console.log('계정이 일치하지 않음.');
return done(null, false, req.flash('loginMessage', '등록된 계정이 없습니다.'));
// 인증 실패 처리
}
// 비밀번호 비교하여 맞지 않는 경우
var authenticated =
user.authenticate(password, user._doc.salt, user._doc.hashed_password);
if (!authenticated) {
console.log('비밀번호 일치하지 않음');
return done(null, false, req.flash('loginMessage', '비밀번호가 일치하지 않음'));
}
console.log('계정과 비밀번호가 일치함.');
return done(null, user);
// 인증 성공 처리 serializeUser에 user 정보 전달
})
});
'Node' 카테고리의 다른 글
Node.js 복습 #1 nodemon, __dirname , static 파일 설정 (0) | 2020.06.20 |
---|---|
Mongoose 의 populate (0) | 2019.12.14 |
(Node.js) Serialize 와 Deserialize 로그인 정보 저장 (1) | 2019.10.29 |
(Node.js)Sokcet 통신을 이용한 1:1 chat (0) | 2019.10.25 |
(Node.js)module.exports 와 exports 차이 (0) | 2019.10.18 |
Comments