あれあの備忘録

アプリ作成の備忘録、IT関連のニュースなどなどいろいろ

powershellでhtdigestファイルを自動生成

こんにちは! ra-men-tarouです

gitもだいぶ認知されている昨今、うちの職場ではまだSVNを現役で使っていたりするのです。。。
f:id:ra-men-tarou:20151025174117p:plain

さて、いろいろなチームが同じリポジトリを触る環境下だとapacheリポジトリを公開し、 さらに案件の人数分ユーザを作ることが求められたりすると思います。
セキュリティの観点から僕はdigest認証を用いる事が多いのですが、apacheから提供されるhtdigest.exeを使うと 最初にコマンドで呼び出したあとにパスワード入力を2回も求めれます。 一人や二人のユーザ追加ならいざ知らず、数十人規模の職場で、かつ公開対象のリポジトリ複数にわたると htdigest.exeでユーザ管理するなど正気の沙汰ではないのです!

そこで今回は最近かじり始めたpowershellを使い、htdigestファイル(digest認証用ファイル)を自動生成したいと思います。

MD5変換を調べる

htdigest.exeではハッシュ値計算にMD5というハッシュ関数を用いているそうです。
Linuxではmd5sumというコマンドが提供されています。

Linuxコマンド集 - 【md5sum】MD5を計算する:ITpro

しかしwindowsには標準ではないようです。 MicrosoftからFCIVユーティリティというものが提供されています。 これを使えばコマンドプロンプトからMD5変換できるのですが、対象がファイルのみとなっています。

d.hatena.ne.jp

MD5変換はファイルの同一性確認をハッシュ値で行うために用いることが一般的なようです。

VectorMD5コマンドというものも公開されています。

www.vector.co.jp

しかし、文字列のMD5変換には対応しているものの出力形式がイケてません。

md5.exe -s "hoge:hoge:hogehoge"
MD5 ("hoge:hoge:hogehoge") = f00f1656e3e26cf04bdc6fc8f5ed72af

powershellMD5変換する

こちらのページの「文字列のMD5ハッシュ値を計算する」を参考にpowershellスクリプトを作成します。

http://blogs.gine.jp/taka/archives/1369

コマンドラインから文字列を与えて呼び出せるようにしたものが下記ソースです。

param($str)

#文字列をbyte型配列に変換する
$data = [System.Text.Encoding]::ASCII.GetBytes($str)
# MD5ハッシュ値を計算する
$md5 = [System.Security.Cryptography.MD5]::Create()
$hash = $md5.ComputeHash($data);
$result = [System.BitConverter]::ToString($hash).ToLower().Replace("-","")
Write-Output $result

このスクリプトmd5.ps1として保存します。

txtファイルからhtdigestファイルを作成する

次にmd5.ps1をラッパーしてhtdigestファイルを作成するスクリプトを作ります。
下記がソースです

param($InputFile,$OutputFile)

$TxtStream = Get-Content $InputFile

#インプットファイルを改行コード区切りでMD5変換する
foreach($InputTxt in $TxtStream -split "\r\n"){
$Md5Str = .\md5.ps1 $InputTxt

#不要なパスワード文字列を切り捨てる
$PasswdPos = $InputTxt.LastIndexOf(":")
$joinStr = $InputTxt.Remove($PasswdPos+1)+$Md5Str

#ユーザ名:レルム:ハッシュ値の形式でファイルに書き出す(Shift-JIS)
echo $joinStr | Out-File -Encoding oem $OutputFile
}

createhtdigest.ps1という名前で上のスクリプトを保存してください。 コマンドラインから「.\createhtdigest.ps1 インプットファイルパス アウトプットファイルパス」で呼び出すと htdigestファイルがアウトプットファイルパスに生成されます。

htdigest.exeで生成されるハッシュ値は「ユーザ名:レルム:パスワード」の文字列をインプットにしています。
(下記ページの.htdigestの構造を参照)

suf.lab: Digest認証用の.htdigestファイルを作る

$InputFileで指定するtxtファイルにはユーザ数文の「ユーザ名:レルム:パスワード」を記入してください。 なお、レルムはhttpd.confで「AuthName "レルム"」で指定するものです。

最後に出力ファイルの文字コードをShift-JISにしています。 はじめはリダイレクトでtxtに出力していたのですが、htdigestでうまく動かなかったためです。 powershellはリダイレクトでファイルに保存するとUTF16で保存されるようです。

さいごに

実は簡単にhtdigetを作りたいなら下記のようなwebサービスがあるのです。

ダイジェスト認証のパスワード生成ツール - 変換商社

でも考えてみてください。何のためにhtdigestを作るのか?
履歴を正確に残すため?不正アクセスを防ぐため?身内でのなりすましを防ぐため?
これらを考慮したとき社内環境で使用する情報をwwwに流すのは気が引けます。
一番望ましいのはオフライン環境で本記事のスクリプトを使って生成することでしょうか?

それでは!