これは、ASP(Active Server Pages) & WSH などで利用できる COM コンポーネントです

多分...

Blowfish の COM を作った。
DES の COM を作った。


はじめに
さて、あなたは対話型、または、とあるシステムの一部となっているような自動処理するクライアント・アプリケーションを作っています。
まぁ、どちらにしてもクライアント・アプリケーションを作っていると仮定します/想像してください。
さて、クライアント・アプリケーションが利用するサーバの認証情報(つまり、メーラのパスワードとか、ブラウザが保持しているWebサイトのパスワードとか)をどこに、どのように保存しますか?
  1. 設定ファイル/レジストリに生のまま、平文で保存
  2. 設定ファイル/レジストリに生のまま、平文で保存するけど、そのファイル/レジストリはユーザごとに厳密なアクセス制御がかかっている
    ルート・ユーザには丸見えって事ですね...
  3. パスワードなので、ハッシュ化(一方向関数、MD5 とか SHA1)しちゃう
    → おぃ!...あなたの使っているアプリケーションで使えないぞ!!(当然のことなので技術的説明は省略)
  4. 特定のキーで復元できるように暗号化する
    → では、そのキーはどうします? 別のキーで暗号化する。ではその別のキーは?....(以下、無限ループ)
  5. 公開鍵システムを使って暗号化する。
    → では、その秘密鍵はどうします? 別の公開鍵で暗号化する。....(以下、無限ループ)
  6. 自作の秘密のアルゴリズムで暗号化
    暗号化の強度は、数学的に証明されています?
    逆アセンブルされたらおしまい....っていうかそれ以前にオープン・ソースで配布できませんね。


という事で、正解がないような気がします。
まぁ、ベターな答えとしては、2 番かな。....となると、パスワードは暗号化しなくてもよい!? 少なくともクライアント・アプリケーションではね。....それでいいのか!?(個人的には無問題って感じですけど...)
(まぁ、あなたが作ったクライアント・アプリケーションにどこかのセキュリティ・エンジニアが「パスワードが平文のまま保存することは問題である」なんて騒いだら、「あ〜ぁ、プログラムも書いたこともない素人が、騒いでいるよ〜、スクリプトが書けるぐらいでエラそうに...」と心の中で思っておきましょう...{毒}) すると、Microsoft は面白い考えを実装してきました。
それが ProtectedStorage と DPAPI です。

Microsoft のコラム「最小限の特権という課題」そのままなのですが、そこで DPAPI が紹介されていましたので、その COM ラッパです。

まぁ、つまり、クライアント・アプリケーションの立場で考えれば、ユーザと同一のプロセスでアクセスするプログラムからは保護できなくてもいいや。という考えです。
まぁ、ここまで(同じユーザが実行する別のプロセスからも保護する)をクライアント・アプリケーションの実装で保護させようとするのも酷ですよね。
それは、クライアント・アプリケーションを実行しているユーザの問題で、クライアント・アプリケーションの実装上の問題ではないような気が私もするわけです。

(それは、つまり「平文のままでファイル/レジストリのアクセス制御を厳密にする」でもいいって事になります
ただ、ProtectedStorage/DPAPI は一応暗号化もしてくれるのでプログラマと利用者の双方にとっても精神衛生上よろしいという事になるんじゃないでしょうか)


また、あるユーザで暗号化したデータは、他のユーザ(例え管理者であっても)では復元できないってところがポイント
つまり、管理者でも復元できない...のかな?

では、VisualBASIC でも使いたいと思うのは、私が VisualBASIC ユーザだからなので、....という事でその COM ラッパとなるわけです。


そもそも DPAPI とは
DPAPI(Data Protection API)とは、データを他のユーザ(他のユーザ・プロセス)への漏えい、改ざんなどを防止する API である。
と言えるんじゃないかな。
元々 WindowsNT?/IE4? では、Protected Storage という保存領域も用意された機能が提供されていたが、Windows2000 からは、暗号化したデータを返してくる API となったようです。
そういう意味で、DPAPI も CryptAPI の一つなのかも知れません。

リンク:


DPAPI の簡単な仕組み
詳細は、他のサイトで調べて。
引数として与えられたデータを、ユーザ(ユーザ・プロセス)と紐付けされた秘密鍵、または証明書と、引数として与えられる「エントロピー」を元に暗号化する。
だから、他のユーザ(他のユーザ・プロセス)からでは、データの解読ができない。
という事です。
ユーザの証明書/秘密鍵が盗まれたら......多分解読されちゃうでしょう。でもそれはもう、Windows を信用しましょう。OS を信用しない限り OS 上でのアプリケーションは書けないでしょう


仕組み
単純です。
暗号化して、文字化けちゃうので、Base64 符号化しているだけです。
BASE64 符号化は、ここを使っています。


使用方法
  1. DPAPI は Windows2000 以降に実装されているそうです。
  2. sCOMmon.dll が必要ですので、ダウンロードして、sCOMmon.dll をシステム・ディレクトリ(%SystemRoot%\System32 {Win64 → %SystemRoot%\SysWOW64})にコピーしてください。
  3. sBase64.dll が必要ですので、ダウンロードして、sBase64.dll をシステム・ディレクトリ(%SystemRoot%\System32 {Win64 → %SystemRoot%\SysWOW64})にコピーしてください。
  4. ファイルをダウンロードします。
  5. ダウンロードしたファイルを解凍しします。
    (LHA は、吉崎栄泰氏が、著作権を所有)
  6. sDPAPI.dll をシステム・ディレクトリ(%SystemRoot%\System32 {Win64 → %SystemRoot%\SysWOW64})にコピー
  7. sDPAPIcom.dll を任意のディレクトリにコピー。
  8. コピーされたディレクトリで、regsvr32.exe を実行して sDPAPIcom.dll をレジストリに登録。
  9. (同梱されている regsvr32.bat を sDPAPIcom.dll と同一ディレクトリにコピーして実行することでも可能。
  10. 以上で、
    VBScript,JScript,VisualBASIC にて、この COM コンポーネントを利用可能。



使い方(VBScript を例にして...)
基本的には
  1. オブジェクトを生成{CreateObject("SDPAPIcom.Encrypt")}
  2. 暗号化、または復号化メソッドの実行{Encrypt() または Decrypt() メソッド}
  3. オブジェクトを解放{Nothing キーワード}

ってな感じです。

ダウンロードしたファイルを解凍すると、test.vbs というファイルがあると思います。
WSH & VBScript でのサンプルです。


アンインストール方法
RegSvr32 コマンドの /u オプションを用いて、sDPAPIcom.dll をレジストリから削除するだけです。
sDPI.dll を削除します。
必要がないようでしたら、sBase64.dll,sCOMmon.dll も削除してください。

免責など
著作権は保持します。
しかし、このソフトを使用したことによって生じた、
いかなる損害についても責任は持ちません。
ソースコードについては、各自の責任において、自由にいじってくれてもいいです。

修正についての提案や、バグレポートなどは、メールにて受け付けています。


DownLoad(sDPAPIcom.lzh as 211,817byte) (sDPAPIcom.lzh.base64)
sDPAPI.dll is 53,248byte(ver1.0.0.5)
sDPAPIcom.dll is 61,440byte(ver1.0.0.5)


変更履歴



COM(sDPAPIcom.dll) メソッド一覧


Encrypt(対象文字列,エントロピー文字列)
EncryptBin(対象データ,エントロピー文字列)
内容 暗号化をしてから、Base64 エンコードを行う。{Encrypt()}
暗号化する{EncryptBin()}
引数 第一引数 : 暗号化したい文字列{Encrypt() は SJIS で処理する。EncryptBin() の場合は、バイナリで(つまりUnicodeで処理する)}
第二引数 : エントロピーを指定する文字列(公けなパスワードって感じ...{意味不明})
戻り値 暗号化され BASE64 エンコードされた文字列{Encrypt()}
暗号化されたバイナリデータ{EncryptBin()}
サンプルコード(WSH & VBScript)
Set Obj = WScript.CreateObject("SDPAPIcom.Encrypt")
ret = Obj.Encrypt("文字列","エントロピー")
Set Obj = Nothing


Decrypt(暗号化されたBase64データ,エントロピー文字列) DecryptBin(暗号化されたデータ,エントロピー文字列)
内容 Base64デコードしたから、復号化を行う{Decrypt()}
復号化を行う{DecryptBin()}
引数 第一引数 : BASE64 化された暗号データ{Decrypt()}
第一引数 : 暗号データ{DecryptBin()}
第二引数 : エントロピーを指定する文字列(公けなパスワードって感じ...{意味不明})
戻り値 復号化された文字列またはバイナリデータ



sDPAPI.dll メソッド一覧


C/C++ 言語用です。...って C/C++ 言語な方は、こんな DLL 経由ではなくて直接呼び出しましょう。
VisualStudio6.0 SP6 に PlatFormSDK(2003/02)のインクルードファイル/ライブラリファイルを使用しています。
適切な Crypt32.lib へのリンクが必要です。

signed long Encrypt(unsigned char*,unsigned long,unsigned char*,unsigned long,unsigned char**,int)
内容 DPAPI を呼び出す
引数 第一引数 : 対象のデータ 第二引数 : 第一引数の長さ(0 の場合は、strlen で長さ計算する) 第三引数 : エントロピーデータ 第四引数 : 第一引数の長さ(0 の場合は、strlen で長さ計算する) 第五引数 : 戻り値のデータを収めるポインタのポインタ(関数内でmallocして返す) 第六引数 : 0:暗号化/1:復号化
戻り値 第五引数のデータサイズ
負数なら、なにかのエラー



その他



その他に、株式会社 フォーカスシステムズ のカオス理論に基づいた暗号エンジン「C4S」の COM ラッパー「ComC4S」もあるよ。

PGP の COM ラッパーもあるよ。
PGP COM ラッパー「NSDPGP.DLL」試用レポート


mail to active@window.goukaku.com