HTMLでパスワード制限
やりたかったのは、自分のブログに置いたログインフォームに、それっぽい動きをさせたい、かな。
HTMLでパスワード制限を掛けたいです。ネットで検索してもちゃんとした物はないので質問しました。CGIやMD5などの暗号化や一般では使わないコード内にパスワードを入れる方法でありますか?
http://q.hatena.ne.jp/1460252561
追記→basic認証などの特殊なとでなありません。
だから、BASIC 認証はダメだと。
「ちゃんとした物」だったら、普通に考えて生のパスワードをソースに書くのはダメだろうから、となると暗号化しか方法は残ってないよなあ。
記事中の一部をパスワードでロックする
ログインフォームっぽいやつ
- ユーザID
- パスワード
不親切な説明
記事中の一部をパスワードでロックする
隠したいコンテンツを CryptoJS.AES で暗号化して、display: none;
で隠しておく。
入力されたパスワードで複合できたら、パスワード入力のところを消して、復号した内容を見せる。
ログインフォームっぽいやつ
こっちは、パスワードチェックを通り抜けた後の処理がバレては意味がないので、それを暗号化しておく。
ハッシュ値で確認というわけにはいかないのだ。
因みにパスワードは、
機械的に集計したような「使っちゃいけないパスワード」ランキングには出てこないけれど、使っちゃいけないパスワードのトップを争うやつを設定してます :-)
なんにせよ、暗号化しなきゃならんのだ
# 最初から「Result」タブを選択した状態にできないんか (´・ω・`)
# 埋め込み用の URL の末尾で順番を指定できた :-)
<script async src="http://jsfiddle.net/LL7885gy/2/embed/result,js,css,html,resources/"></script>
CryptoJS
検索で最初に引っかかった CryptoJS の AES を使ってる。
多分、メジャーな奴なのだと思うのだけれど、ドキュメントが少ないなあ。
「復号に失敗したということ」を検出をする API が分からん。
UTF-8 にエンコードしようとしたときに、復号に失敗すると例外が飛んでくるようなので、それを使ったけど。
キー
キーは、パスワードに salt を足して、そのハッシュ値を使ってる。
evpkdf.js EvpKDF#compute()
salt は、Math.random を使ってる。
cipher-core.js : OpenSSLKdf#execute()
core.js : WordArray.random()
Math.random は、現在時刻を種に使ってるので、復号するときの salt はどうするんだと思ったら、暗号化データに埋め込んでいるようだ。
cipher-core.js : PasswordBasedCipher#decrypt()
decrypt: function (cipher, ciphertext, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
cfg.format は OpenSSLFormatter で、CryptoJS.format.OpenSSL 。
先頭 16byte が、マジックナンバー + salt になっている。
cipher-core.js : OpenSSLFormatter#parse()
リンク集
- https://code.google.com/archive/p/crypto-js/
本家 - https://github.com/brix/crypto-js
GitHub - https://crypto-js.googlecode.com/svn/tags/3.1.2/src/
SVN @ Google Code - https://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/
SVN @ Google Code
複数のファイルに分かれてるライブラリとかを、ひとつの .js にまとめてくれてるやつ。 - https://blog.potproject.net/?p=403
AES での暗号化の実例。
キーはハッシュ化しなくても暗号化には使える。 - http://qiita.com/yaegaki/items/9701317a76a35bea1684
CryptoJS では、パスフレーズにひと手間加えてキーを作ってるよ、という話。CryptoJS で暗号化したものを別のもので復号するときに、ここんところを知らなくちゃいけない。 - http://memolog.org/2015/08/try-cryptojs.html
encrypt メソッドの戻り値ではなく、toString した文字列を decrypt で復号できる。
サーバサイドが Node.js だと、キーをどうやって作ってるかを気にしなくて良い。 - https://hibara.org/blog/2016/02/15/cryptojs/
AES CBC モードでの暗号化 - http://qiita.com/cognitom/items/041b48d8cf746ab54f06
ここでは aes.js を googlecode.com ではなく github.com の方を使っているのだけれど、GitHub の RAW は Content-Type: text/plain で返してくるので、MIME タイプが違うとかでブラウザにはじかれちゃう。
なので、githack.com を経由して取り込んでる。
暗号化以外の方法
No.2 の回答で言及されている「イヌでも...」のやり方は、手軽で割りとイケてると思うけど。
「問題ありあり」というほどじゃない。
- 複数のコンテンツにガードをかけられない
→ ファイル名やディレクトリの一部に使うか、頑張ってマッピングする - ファイル名に使えない文字をパスワードに含められない
→ encodeURIComponent とかを使う
くらいで、けっこう使い物になるんじゃないかという気はする。
コンテンツの URL を自分で決めることができることと、コンテンツに自動でリンクが張られない、ということが条件になるので、ブログに設置するには、ちょっと厳しいかな。
最後に
いちばん素直(特殊じゃない)なのは BASIC 認証なんだけどね。