Java:ログインパスワードを暗号化する
Webアプリケーションなどでは,アクセス時にパスワードによるログイン認証を行う場合があります。
ここではその具体的な実装のうち,データベースやパスワードファイルに格納するログインパスワードの暗号化について述べてみたいと思います。
【概要】
複数のユーザが個別にユーザ名とパスワードを設定する場合,そのアカウント情報はデータベースなどに保存するようになると思います。
このときパスワードをそのまま保存してしまうと,パスワードはデータベースを閲覧できるすべての人に知られてしまいます。また,Base64変換や元に戻せる暗号にした場合でも,元に戻せる技術をもった人にパスワードを知られてしまう可能性があります。そのため,パスワードを保存する場合は不可逆暗号にするのが一般的かと思います。
不可逆暗号とは元に戻せない暗号です。不可逆暗号を使ってパスワード認証を行うには,暗号化したパスワードをデータベースにあらかじめ保存しておき,ユーザがログインした時にユーザが入力したパスワードを暗号化して,データベースに保存されている暗号化されたパスワードと同一になるかどうかで正しいパスワードか判断することができます。不可逆のメリットとしては,元に戻せないのでパスワードの漏洩が防げると同時に,データベースを閲覧できる人にパスワード窃盗の嫌疑がかかるのを防ぐことができます。デメリットとしては,元に戻せないのでユーザがパスワードを忘れてしまったらパスワードを登録し直すしか手がないことです。
パスワードだけを暗号化した場合,同じパスワードの人がいた場合に同じ暗号データがデータベースに登録されてしまい,データベースを閲覧した人に同じパスワードであることがわかってしまう可能性があります。この対策としては,(ユニークな)ユーザ名とパスワードを加えて暗号化すれば良いかと思います。
【Javaによる不可逆暗号の実装】
Javaにはメッセージダイジェストを作成するクラスがありますので,これを使って不可逆暗号を作ることができます。具体例として下記のようなコードになります。
なお,このコードではユーザ名がNULLであることを想定していません。なぜならユーザ名はアカウントを特定するユニークキーなので,必須であるべきだからです。ユーザがユーザ名を入力しなかった場合は,このメソッドを呼ぶ前にエラーではじくべきです。
※このコードでは,メッセージダイジェストをテキストに変換するために,当初Base64エンコードしていましたが,バイトごとの数値を文字列に変換して連結する実装に改めました(2015/02/16)
import java.security.*; /** * パスワードを不可逆暗号化する. */ public class PassDigest { //------------------------------------------------------------------ /** * ユーザ名とパスワードでメッセージダイジェストを作成し文字列化して返す. * @param userName ユーザ名. * @param password パスワード. * @return 生成したダイジェスト. * @throws NoSuchAlgorithmException Java実行環境にSHA-1が実装されていない. */ public static String build ( String userName, String password) throws NoSuchAlgorithmException { StringBuilder buff = new StringBuilder(); if (password != null && !password.isEmpty()) { MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(userName.getBytes()); md.update(password.getBytes()); byte[] digest = md.digest(); for (byte d : digest) { |
※上記コードでは,整形のため全角スペースを使用している部分があります。
【著作権表記】上記コードを含む本ブログのプログラムコードは,私的利用可,商用利用可,改変しての利用可です。利用の際に作者に許諾を得る必要はありません。
■関連情報
Sun:Java暗号化アーキテクチャ API の仕様およびリファレンス
クラスMessageDigest(Javadoc)
■関連書籍をAmazonで検索:[Java]
●Javaで作って学ぶ暗号技術 - RSA,AES,SHAの基礎からSSLまで
←この記事が役に立ったという方はクリックお願いします。
| 固定リンク
「プログラミング」カテゴリの記事
- シェルスクリプト:「.svn」ディレクトリを一括削除する(2015.03.23)
- JavaScript:excanvasを使ってWebページに画像を表示する(2012.05.07)
- C言語:TRUEとFALSEの値(2012.05.06)
- Java:CSVパーサを作る(その3) - RFC4180対応 後編(2008.06.13)
- Java:CSVパーサを作る(その2) - RFC4180対応 前編(2008.06.12)
「Java」カテゴリの記事
- Java:Reader/Writerにおけるclose()メソッド呼び出しの流儀(2015.06.29)
- Java:例外が起こったときに実行されるコードとされないコード(2015.03.31)
- Java:前回作成したコードの処理速度を比較する(2015.03.15)
- Java:数値を3桁ごとのカンマ区切りの文字列にする(2015.03.02)
- Java:全角の数値文字列を数値として受け付ける(2015.01.19)