Transact-SQLでパスワードをマスクする


[言い訳]
普通はパスワードなんて表示することは無いと思うし,
そもそも生パスワードをDBに入れるものなのかはわかりませんが,
そこら辺の事情は下に感知できるところではないのです.

パスワードの文字数分マスク文字列を被せる

プログラム側で操作するのが一番簡単ですが,
Transact-SQLでやっちゃうのが応用が利いていいです.

Transact-SQLの文字列関数群

使う関数を次の表に示します.

関数名 用途
REPLICATE 文字列を指定回数繰り返す
LEN 文字列の長さを返す


使い方は簡単.PASSWORDというカラムに入っているパスワードを文字列”*”でマスクしたい時は次のようにします.

REPLICATE('*', LEN(PASSWORD))

当然,パスワードの情報なのですから文字数だって見せたくないということはよくあると思います.
それなら,こうしてしまえばOK

REPLICATE('*', 5)

DataGridViewとの連携

こんなものが何に使えるかといいますと,
DataGridViewの標準機能では,
通常のTextBoxのように値をマスクできません.

そのため,DataGridViewにデータソースをバインドして,
その中のパスワード項目をマスクしたい時にどうするかという問題があります.
この時のやり方としては,
大きくわけて3種類考えられます.
一つは,DataGridViewにはめこめるパスワードをマスクする機能を持ったコントロールを作成すること.
一つは,DataGridViewに値を表示する時点で値を書き換えること.
そして,最後の一つがバインドするデータソース自体にマスクしたパスワード文字列を持つことです.

単純にDataGridView側のパスワード文字列の項目に”*****”と表示したいだけなら,
デフォルト文字列を”*****”にしてその項目にはどのカラムもバインドしなければいいだけです.
しかし,DataSetとTableAdapterにBindingSourceを被せて表示,更新,削除を行う方法
*1で,パスワードも変更できるようにしようとすると,様々な面で矛盾が生じます.

そもそも,データソースをバインドすると
DataGridViewの値とデータソースの値が二重に存在することになり,
値に対する処理はどちらか一方にしなければ矛盾が生じます.*2
データベースに近いデータソース側の値を集中管理した方が便利な場合には,
上記の方法を用いてデータベースから値がやってくる瞬間に既にマスクされているようにすると有利です.

具体的には,バインドするデータセットでパスワード列を二つ持ちます.
表示したいのは,マスクされているパスワードカラムで,
更新に使いたいのは真の値を持ってデータベースと直接繋がっているパスワードカラムです.
ここでは,前者のカラム名をVIEW_PASSWORD,後者をPASSWORDとします.

PASSWORD VIEW_PASSWORD
初期表示 表示しない マスク文字列
編集 VIEW_PASSWORDに同期 普通に編集
更新 値を更新 データベースに反映しない

SQL文で書くと,こんな感じ.

SELECT PASSWORD, REPLICATE('*', LEN(PASSWORD)) AS VIEW_PASSWORD
FROM DB

DataGridViewを通じた編集に対するデータセット上でのVIEW_PASSWORDとPASSWORDの同期は,
DataTableのColumnChangedイベントで行うと良いです.*3

*1 : VisualStudio2005のデフォルト

*2 : というよりも,一元管理することによりコードが単純化して保守しやすくなるメリットが大きいです

*3 : DataGridViewのセル上で同期を取るよりもDataTable上で同期を取った方がいいです

終わりに

自分がこの処理をやりたくてWebを検索しましたが,全然資料が見つかりませんでした.
この程度のこと,Tipsとして記すほどでもない自明のことなのかもしれませんが,
一応自分の作業メモとして残しておきます.
Transact-SQLもDataGridViewも使い慣れないので難しい…….

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>