パンジェンシーの「汗だく開発日誌」

システム開発の備忘録です。

【Node.js】sechashを使ってパスワードをハッシュ化

パンジェンシーです!

 

f:id:x-fieldatts:20150502134035p:plain

 

プログラミング関連は、久々の更新です!

express-sessionを使ったログイン機能を実装するところまでは書いたと思います。

 

pangency.hatenablog.com

 

今回はその続きです。 

 

 

パスワードハッシュ化の必要性

以前のエントリーにも書きましたが、

このアプリ、そのまま実環境で運用するには少し危険です!

何故かというと、パスワードが平文のまま、データベースに保存されているからです!

なので、今回は「sechash」というモジュールを使って、パスワードをハッシュ化してみます。

 

環境

  • Ubuntu 14.04 LTS
  • node.js v0.12.14
  • MongoDB 3.0.12

ちょっと以前よりバージョンアップしました。
今のところ、ちゃんと動いている様子…。

パスワードハッシュ化モジュール「password.js」を作ろう!

機能毎にファイルを分けたほうが、メンテが楽なので、パスワード用の関数をまとめたモジュールとして、「password.js」を作りました。


password.js

// モジュールの読み込み
var sechash = require('sechash');

// パラメータの設定
var opts = {
    algorithm: 'sha512', // アルゴリズム
    iterations: 2000, // 繰り返し回数
    salt: 'shimenoudon' // ソルトの設定
};

// 関数
var password = {
    createHash: function (password) {
        return sechash.strongHashSync(password, opts);
    },
    check: function (password, hash) {
        return sechash.testHashSync(password, hash, opts);
    }
};

module.exports = password;

 

関数

createHash パスワードを引数として与えると、返り値としてハッシュ化されたパスワードを返す関数です。
check 引数"password"をハッシュ化し、引数"hash"と照合します。一緒ならtrueを返し、違うならfalseを返します。

パラメータについては、今回は適当に設定していますが、より強固なセキュリティにするためには、工夫が必要なようです。

これで、モジュールの作成は完了です。

sechashモジュールをインストールしよう!

先ほど作ったモジュールで使用するsechashモジュールを、プロジェクトにインストールしましょう。

$ sudo npm install sechash --save

パスワード関連のコードを修正しよう!

では、以前のエントリーで作成した、ログイン機能アプリを例に、コードを修正していきます。

データベースのスキーマの修正

model.jsを修正した場合の例を書いておきます。

model.js

password: String → hash: String

新規登録部分のコード修正

add.jsを修正した場合の例を書いておきます。

add.js

var express = require('express');
var router = express.Router();
var model = require('../model.js');
var User = model.User;

// password.jsを読み込む
var password = require('../password.js');

router.post('/', function(req, res) {
    var email = req.body.email;
    var pass = req.body.password;

    User.where({
        email: req.body.email
    }).find(function(err, data){
        if(err){
            return handleError(err);
        }
        if(data.length === 0){
            // 登録可能な場合
            var hash = password.createHash(pass);
            var newUser = new User();
            newUser.email = email;
            newUser.hash = hash;
            newUser.save(function(err) {
                if (err) {
                    res.redirect('back');
                } else {
                    res.redirect('/');
                }
            }
        }else{
            // 既に登録されているemailの場合
            res.render('login');
        }
    });
});

module.exports = router;

ログイン部分のコード修正

login.jsを修正した場合の例を書いておきます。

login.js

var express = require('express');
var router = express.Router();
var model = require('../model');
var User = model.User;

// password.jsを読み込む
var password = require('../password.js');

router.get('/', function(req, res) {
    res.render('login');
});

router.post('/', function(req, res) {
    var email = req.body.email;
    var pass = req.body.password;
    var query = {
        "email": email
    };
    User.find(query, function(err, data) {
        if (err) {
            console.log(err);
        }
        if (password.check(pass, data.hash)) {
            req.session.user = email;
            res.redirect('/');
        } else {
            res.render('login');
        }
    });
});

module.exports = router;

以上でコードの修正は完了です。

新規登録してみて、ハッシュ値で保存されるか確かめてみましょう。

まとめ

今回は、パスワードをハッシュ化する方法を書きました。

個人情報を取り扱う場合は、こういうセキュリティ面にも注意を払っておく必要があるので大変ですね…。

webアプリを公開する場合は、他にも、クロスサイトスクリプティングやら、クロスサイトリクエストフォージェリやらのサイバー攻撃対策も必要になってきます。

機会があったらその辺も書こうと思います。

では、また!