パスワードをデータベースに保存するときは、一緒に塩を入れよう
セキュアに保存する -> 漏れた場合を想定する
データベース(以下DB)にパスワードを保存するとき、そのまま
(平文で)保存してはいけません。データが漏れた場合に、パスワードが
見た瞬間わかってしまうからです。
パスワードを保存する場合、暗号化してからDBへインサートします。
実装例
手法は多種多様ですが、ここではSALTを使って暗号化
してみたいと思います。PHP + MySQLでの想定です。(ちなみにPDO)
SALTはランダムな文字列で、各ユーザごとにそれぞれ異なる
ものを用意します。
<?php /* 暗号化関数 */ function saltAngo($password, $salt) { $saltPassword = crypt($password, $salt); return $saltPassword; } /* ランダムな文字列を生成 */ function mkSalt($length = 8) { return substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyz', $length)), 0, $length); }
<?php /* 上記ファイルの関数をrequire_onceなどで使えるようになっているとします。 */ $user = 'hoge'; $password = 'hogehoge'; $stmt = $pdo->prepare('INSERT INTO userdata SET user = ?, password = ?, salt = ?'); // トランザクション開始 $pdo->beginTransaction(); try { $stmt->bindValue(1, $user); $salt = mkSalt(); // ランダムな文字列作成 // パスワードはsaltAngo関数で暗号化 $password = saltAngo($password, $salt); $stmt->bindValue(2, $password); $stmt->bindValue(3, $salt); // 使ったSALTもDBへ保存 $stmt->execute(); // コミット $pdo->commit(); } catch (PDOException $e) { // エラーでロールバック $pdo->rollBack(); throw $e; }
ログイン時は、DBに保存された同じSALTを使います。同じ暗号化のロジックを使用すれば、同じ結果が
戻ってくることを利用するのです。
<?php /* 実際はちゃんと無毒化しましょう */ $user = $_POST['user']; $password = $_POST['password']; $stmt = $pdo->prepare('SELECT * FROM userdata WHERE user = ?'); $stmt->bindValue(1, $user); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!empty($row)) { $salt = $row['salt']; $password = crypt($password, $salt); // 保存時と同じSALTで復号化 // パスワードが一致しているか if ($row['password'] === $password) { echo 'ログイン完了'; } else { echo 'ユーザ名かパスワードが違います'; } } else { echo 'そのようなユーザは登録されていません'; }
ここでは説明を簡単にするため、弱い暗号化で済ませています。実際には、もっと
強いロジックを考えましょう。
strictモードで厳格なjavaScriptを書こう
strictモードとは?
近頃見られるようになった下記のような記述。javaScriptを書く際、必須になりつつあります。
(function() { 'use strict'; // 処理 })();
jsファイルの先頭に
'use strict';
と記述することにより、strictモードを 宣言することができます。strictモード下では、厳格なjavaScriptを書くことが求められるので、必然的に バグの混入を減らすことができます。
ちなみに
(function() { })();
の部分は即時関数と呼ばれ、スコープ汚染を防ぐために用いられるものです。ここではテーマの範囲外になるので 割愛します。
効果
- 暗黙的なグローバル変数の禁止
- 代入不可なプロパティへの代入の禁止
- 削除できないプロパティの削除の禁止
- 関数の引数名の重複の禁止
- 幾つかの識別子は予約語にするため使用禁止(staticとか)
- 8進数表記の禁止
- eval 変数、arguments 変数の宣言禁止
- with 禁止
etc...って感じですね。
下の6、7、8はいいとして、1から5の効果は僕としては、かなり、ありがたいと思います。
代表効果の例
strictモードには、いくつかの効果がありますが、そのうちのもっとも基本的な効果がvar
のつけ忘れを防げることです。上記の効果のうちの1.暗黙的なグローバル変数の禁止に当たる機能
です。
(function() { 'use strict'; var x = 'hello'; // ok y = 'goodnight'; // error })();
コンソールで確認すればUncaught ReferenceError: y is not defined
と注意されているはずです。ちょっとしたことですが、javaScriptは基本ゆるい言語
なので、こういうのが案外、助けになったりします。
注意点
- IE10以下ではサポートされていない
- 先頭以外でstrictを宣言しても strict モードにならない
1はそのままの意味です。Internet Explorerは昔からjavaScriptと 相性が悪いのです。
2は下記のコードを見てもらうのが早いです。
(function() { var x = 'hello'; 'use strict'; y = 'goodnight'; // エラー吐かない // 両方の変数がコンソールに出力されてしまう! console.log(x); console.log(y); })();
参考
Vagrant + CentOS6.4 + rbenv でRuby環境構築
Step.0 前提条件
- VirtualBoxインストール済み
- Vagrantインストール済み
- WindowsならばPuTTY or TeraTermインストール済み
Step.1 Vagrant上CentOSを導入
ターミナルから作業ディレクトリに移動。なければmkdir
でつくります。
Vagrantbox.esから 使えそうなCentOSを探しましょう。今回はこの
を使用。Copyのボタンを押して、ターミナル(コマンドプロンプト)に戻ります。
vagrant box add centos-testhttps://github.com/2creatives/vagrant-centos/releases/download/v6.4.2/centos64-x86_64-20140116.box
と打ち込んで実行。Copyボタンを押しているならば、URL部分はコピーの方が早いです。
centos-testの部分はボックスの名前ですが、自分のわかるものであれば好きな名前で
構いません。2、3個であれば問題ないですが、多くなってくると混乱します。間違えて違うボックスを
消してしまったりしないようにしましょう。
ボックスが追加されているか確認するには
vagrant box list
と打ち込みます。centos-testと追加されていれば成功です。
続いて、作業用のディレクトリを作成し、その中に移動します。もちろん自分のつけたい名前でオーケイです。
mkdir centos-test cd centos-test
そこまでできたら
vagrant init centos-test
と入力。centos-testの部分は自分のつけたディレクトリ名を打ち込ましょう。
ディレクトリ内にVagrantfileというファイルが作成されれば成功です。
次に、このVagrantfileを編集します。好みのエディタで開いて
config.vm.network "private_network", ip: "192.168.33.10"
という部分の#を外しましょう。
たいていは192.168.33.10だと思いますが、もし、ipの数字部分が違う人がいればメモするなり
しておきましょう。
いよいよ仮想マシンを起動します。起動するには、Vagrantfileが存在するディレクトリ下で
vagrant up
と入力するだけです。起動したか確認するには
vagrant status
と打ち込みます。runningと表示されれば無事起動しています。
Macならばvagrant ssh
を使い、WindowsならばPuTTYかTeraTarmを
使って仮想マシンに接続します。このとき、ipの番号が書かれていたものと違っていた人は、書かれていた
番号を使って接続しましょう。
接続に成功するとユーザ名を聞かれます。ユーザ名はデフォルトでvagrant
となっています。
次にパスワードを聞かれますが、パスワードも同じくvagrant
です。
無事入ることができたら少し休憩でもしましょう。
仮想マシンを切断するにはexit
仮想マシンを止めるにはvagrant suspend
かvagrant halt
を使います。
Step.2 gitを導入
gitを使うので
git --version
でgitが入っているか確認します。入っていなかったら
sudo yum install -y git
でインストール。
BreakTime なぜrbenvを導入するか
rbenvとは、複数のバージョンのRubyを管理できるコマンド群です。今まで知らなかったのですが、アールビーエンヴとかアールベンヴって読むらしいですね。
して、なぜ普通にyum install ruby
としないかと言うと、2系のRubyが入らないからです。
このコマンドだと、1系のRubyが入ってしまいます。(2016年6月 現在)
もちろん、それでオーケイだという方は面倒な手順をふまずに、yum
を使ってインストールしてもらっても
構いません。
Step.3 rbenvを導入
いちいちsudoを打つのが面倒なのでルートユーザになります。
su -
パスワードは初期設定でvagrantでした。
つづいて、/usr/local/src下に、rbenvのリポジトリをクローンします。
git clone git://github.com/sstephenson/rbenv.git /usr/local/src/rbenv
つづいて、パスを通します。
~/.bash_profile
に書き込んでしまうと、実行ユーザしか読み込んでくれないので、/etc/profile.d/
下
に、rbenv.shというファイルをつくって設定を書き込みます。
echo 'export RBENV_ROOT="/usr/local/src/rbenv"' >> /etc/profile.d/rbenv.sh echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile.d/rbenv.sh echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh source /etc/profile.d/rbenv.sh
ちゃんと書き込まれているかを、エディタで開くかcat
コマンドで確認しましょう。
確認したら、exec $SHELL -l
とコマンドを打ち、シェルを再起動します。(exitで一度出ても良い)
ルートユーザから一般ユーザに戻ってrbenv -v
と打ち込んでバージョンが表示されればオーケイです。
Step.4 ruby-buildの導入
rbenvはRubyのバージョンを管理するためのコマンド群なので、これだけでインストールすると普通にyum install ruby
とするのと変わりません。rbenvディレクトリ下にpluginsというディレクトリをつくり、その中にruby-buildのリポジトリをクローン
します。
git clone git://github.com/sstephenson/ruby-build.git /usr/local/src/rbenv/plugins/ruby-build
Step.5 依存パッケージのインストール
rubyをインストールするにあたり必要なものをまとめてインストールしてしまいましょう。
sudo yum install -y gcc make openssl-devel readline-devel libffi-devel zlib-devel libcurl-devel
1個ずつgrep
等を使ってすでに入っているか確かめて行っても良いですね。
っていうかこんなにインストールしなくていいような気がする・・・。
Step.6 エラーの解決
rbenv install --list
でインストールできるRubyのバージョンが確認できます。
当然インストールするのは2系。ここでは2.2.2をインストールしてみます。
(ここで注意点があります。ルートユーザになりましょう。グループ作成をしておらず、グループがrootの
ままになっているからです)
rbenv install 2.2.2
ここで「足りないものがあるよ」と怒られた場合には、それをインストールしましょう。ただ、僕の場合は 少し違いました。
mkdir: cannot create directory `/usr/local/src/rbenv/versions/2.2.2': Permission denied
Permission denied
だからRuby2.2.2のディレクトリを作成できない、と言われているようです。
ちょっと危険ですが
chmod -R 775 rbenv
か
chmod -R 775 versions
でアクセス権を変更しました。(どっちでやったか忘れた)2番目の7は、グループのアクセス権を表しており、それの読み、書き、実行のすべてができる
ように許可したわけですね。ls -l
で確認すればわかるようにroot root
となっています。2番目のroot
がグループを表しているわけです。こういうのは、あまり良くないですが、練習用の仮想環境下なので今回はこれで良しとします。
もう一度インストールを試みると今回は上手くいきました。念のため、本当に成功したか下記のコマンドで確認します。
rbenv versions
インストールはできましたが、まだ、Rubyは使えません。
rbenv global 2.2.2
とコマンドを打ち、「2.2.2のバージョンを使うよ」と宣言しましょう。ruby -v
で確認して2.2.2のバージョンが表示されれば、
あとは自由にRubyを使うことができます。
step.7 バージョンの切り替え
せっかくなので、もう一つ違うバージョンをインストールしてみます。
rbenv install 2.3.0
もちろん違うバージョンをインストールしただけでは、前のバージョンのままです。
rbenv vesions
で確認すると、2.2.2のバージョンの前に * がついていると思います。現在使っているバージョンを表す記号です。
新しくインストールしたバージョンを使うことを下のコマンドで宣言します。
rbenv global 2.3.0
もう一度rbenv vesions
で確認すると、アスタリスクが新しいバージョンの方についていると思います。
これで新しく追加した方のRubyが使えるようになりました。
rbenv便利ですね!