HTMLでパスワード制限

やりたかったのは、自分のブログに置いたログインフォームに、それっぽい動きをさせたい、かな。

HTMLでパスワード制限を掛けたいです。ネットで検索してもちゃんとした物はないので質問しました。CGIMD5などの暗号化や一般では使わないコード内にパスワードを入れる方法でありますか?
追記→basic認証などの特殊なとでなありません。

http://q.hatena.ne.jp/1460252561

だから、BASIC 認証はダメだと。
「ちゃんとした物」だったら、普通に考えて生のパスワードをソースに書くのはダメだろうから、となると暗号化しか方法は残ってないよなあ。

記事中の一部をパスワードでロックする

閲覧するためにはパスワードが必要です

U2FsdGVkX1/uHkyBgQcDmOLv0QuEG3iJolffcOE67c+xxVZ8pfTMPSUy0VZKMPpfLrE9JOOZJa2sjzIoAiPFqgvUANBwmuq2N5A8MA85fMfdj4KFtI3xHcnF5aiuIkFmO2IPLUg8MVhcYwaMl6yuLlVsJ5iO7FTUCFS7+cbg//PK3Z1QPUtGV21WgqKq5HW9gNaMdjSRRslVTXaJb/q5BDNpLdGn1QvxxJ4dixypCJPBzSa/wkAVn81Ls8dwpDx17/F7784MAeOMRK3+TxW1o5Quqnq9iF08HqFpfQ5+EmP0RuF8w8kOF9LXWZLbNxD2zYz3NHQOYOwasW+xvTtVvAMXAzTXJCzsIS7QHlIYjqiHXlqRiH5QLTKN0v1hn/8BkTOYkTu+5vM3Jcl8R2rVU1GAeVQsf9DYCxsq70p3BVoK/Y2P7N6f4VkS1cIogJoNJy489s36E+3hS6zDVuAM+ZPE9Sdn/7KCZHHynZB5Vk7qzWv69+Te1lVWEHIXO2O+xDwEgsnqhcUesH3iijh1Lvs15LM5KS7OssM+XHd79MqvPggxtgJyrnv7unix4wDxcdB4nh77H7GIIO+KqfrtRBBsRN3zyGbcouFZ42JUCsUGST0z2x1w4rFAv2zFVAKY+t6/Oxd29uFmARE/RFJYNM6Pkfw6Kb4fgHobFnTR7dBPg55G03vkPUFbx6YVWfRyP3x/lwHR6wFovCX78ZZ+58A6Cpc714u6E+qbMBOtFfs=

ログインフォームっぽいやつ

不親切な説明

記事中の一部をパスワードでロックする

隠したいコンテンツを 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()

リンク集

暗号化以外の方法

No.2 の回答で言及されている「イヌでも...」のやり方は、手軽で割りとイケてると思うけど。
「問題ありあり」というほどじゃない。

  • 複数のコンテンツにガードをかけられない
     → ファイル名やディレクトリの一部に使うか、頑張ってマッピングする
  • ファイル名に使えない文字をパスワードに含められない
     → encodeURIComponent とかを使う

くらいで、けっこう使い物になるんじゃないかという気はする。

コンテンツの URL を自分で決めることができることと、コンテンツに自動でリンクが張られない、ということが条件になるので、ブログに設置するには、ちょっと厳しいかな。

最後に

いちばん素直(特殊じゃない)なのは BASIC 認証なんだけどね。