japan.internet.comThe Internet & IT Network
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2009年7月4日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
デベロッパー2005年11月1日 10:00

Blowfish暗号化データをMSXML2 DOMオブジェクトに直接ロードする

海外海外internet.com発の記事
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • Buzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!
  • この記事をokyuuへインポート

はじめに

 MSXML2ライブラリを使用するときは、通常は、IXMLDOMDocumentのインスタンスを生成し、そのload関数を呼び出す(ここでファイル名のBSTR表現を引き渡す)ことで、XMLファイルをディスクからDOM(Document Object Model)オブジェクトにロードします。しかし、私は最近、セキュリティ上の問題から、まずメモリ内でXMLデータを復号してからそのメモリを(ディスクに書き出さずに)DOMオブジェクトにロードしなければならない、という事態に遭遇しました。私はオープンソースの例の中からこれを行う方法を探したのですが、意外にも見つけることができませんでした。そこで、このタスクを行うためのいくつかのヘルパー関数を作成しました。私と同じような状況に置かれた他の人々にも役立つと思うので、ここで紹介させてもらいます。

DecryptFile2Bstrヘルパー関数

 説明を続ける前に、1993年にBruce Schneier氏がBlowfish暗号化アルゴリズムを発表して以来、多くの実装が登場していることを述べなければなりません。私は、高速で信頼できるデータ暗号化/復号のための暗号化手段を必要としていたのですが、その目的にはGeorge Anescu氏による実装を使用するのが特に簡単であると思いました。そのため、私の関数は、George Anescu氏によるCBlowFishクラスを使用して暗号化されたデータを扱うようにできています。

 私が解決策を探しているときに最初に学んだことは、IXMLDOMDocumentオブジェクトがloadXMLという関数をサポートしており、この関数は解析対象のXMLを表すBSTR値を取るということです。クライアント側をできるだけ簡潔にする、というのが私のコーディングスタイルなので、今回も、クライアント側から呼び出せる1つの関数で、ほとんどすべてのことを行わせたいと考えていました。そこで作成したのが、入力ファイル名とパスワード(どちらもcharポインタ)を取り、BSTR値を戻すDecryptFile2Bstr関数です(下記参照)。戻されたBSTR値は、IXMLDOMDocument::loadXML関数で使用することができます。

 下記のコードからわかるとおり、DecryptFile2Bstr関数はCBlowFishオブジェクトをインスタンス化した後、CBlowFish::Decryptを呼び出す前に、私が作成したもう1つのヘルパー関数であるGetFormattedFileContentを呼び出します。GetFormattedFileContent関数とCBlowFish::Decrypt関数の両方に使用されるデータがcharバッファという形式なので、DecryptFile2Bstr関数は呼び出し元に戻る前に標準COMユーティリティ関数ConvertStringToBSTRを呼び出します。

BSTR DecryptFile2Bstr(char* inputFileName, char* password)
{
  try
  {
    int requiredFileSize;
    CBlowFish oBlowFish((unsigned char*)password, sizeof(password));
    char *buffer = GetFormattedFileContent( inputFileName,
                                            requiredFileSize );

    oBlowFish.Decrypt((unsigned char *)buffer, requiredFileSize);

    return _com_util::ConvertStringToBSTR(buffer);
  }
  catch ( char *ex )
  {
    throw ex;
  }
}

 Blowfishアルゴリズムは8バイトのブロックをベースとするため、GetFormattedFileContent関数はそのブロック単位でデータをメモリに読み込みます。このルールに適合させるために、関数の最後でパディングを行っていることに注目してください。

char* GetFormattedFileContent(char *filePath, int &requiredFileSize)
{
  FILE *fp = fopen(filePath, "r+b");

  int fileSize = FileSize(fp);
  int index = fileSize;

  if ( (fileSize % 8) != 0 )
    requiredFileSize = ((fileSize / 8) + 1) * 8;
  else
    requiredFileSize = fileSize;

  char *buffer = new char[requiredFileSize + 1];
  fread(buffer, sizeof(char), fileSize, fp);
  buffer[fileSize] = 0;
  fclose(fp);
  while (index < requiredFileSize)
    buffer[index++] = 0;

  return buffer;
}

int FileSize(FILE *fp)
{
  char buffer[1];
  int count = 0;
  fseek(fp, 0, SEEK_SET);
  while (fread(buffer, sizeof(buffer), 1, fp) != 0) count++;
    fseek(fp, 0, SEEK_SET);
  return count;
}

DecryptFile2Bstr関数の使用

 データがCBlowFishクラスを使用して暗号化されている場合は、下記の太字で示した2行のコードで、そのデータをXML DOMオブジェクトにロードすることができます。

#import <msxml4.dll& named_guids
using namespace MSXML2;

...

::CoInitialize(NULL);

MSXML2::IXMLDOMDocumentPtr plDomDocument;

HRESULT hr = plDomDocument.CreateInstance(MSXML2::CLSID_DOMDocument);
if (SUCCEEDED(hr))
{
  // load the file as an XML document
  BSTR = DecryptFile2Bstr(L"MyFile.xml", DEFS_ENC_PASSWORD);
  variant_t vResult = plDomDocument->loadXML(xmlfile);

  ...

今後について

 MSMXL2 IXMLDOMDocument::loadXMLを私のヘルパー関数と組み合わせることにより、ディスクへの復号を行うことなく、クライアントの機密データをメモリに読み込み、復号することができました。また、これらの関数を拡張し、CBlowFishで暗号化されたデータを持つファイルを指定ファイルに復号するヘルパー関数(DecryptFile2File)や、プレーンASCIIデータをCBlowFishで暗号化されたファイルにするヘルパー関数(EncryptFile2File)などを組み込めるようにしました。もしこれらの関数を必要としている方、あるいは興味をお持ちの方がいましたら、これらも公開しようと思います。

著者紹介

Tom Archer(Tom Archer)
.NETプログラマの教育・指導、プロジェクト管理コンサルティングを専門とする研修会社、Archer Consulting Groupを経営。同社がどのように貴社の開発コストを削減させ、ソフトウェアを市場に早く送り出し、製品からの収入を増やすのに役立ってくれるのかを知りたい場合は、同社のWebサイトをお訪ねください。
このエントリーを含むはてなブックマーク この記事をクリップ!
BuzzurlにブックマークBuzzurlにブックマーク Yahoo!ブックマークに登録
この記事をokyuuへインポート
最新トップニュース
データメーション
【データメーション】
中国が「Green Dam」フィルタ規制を撤回(7月1日)
Graphic Design Forum
【Graphic Design Forum】
Chris Dickman(6月25日)
プライバシー ジャパン・インターネットコム版
【プライバシー ジャパン・インターネットコム版】
グーグル・ストリートビューの問題について総務省の見解(6月23日)
エンジニアの独り言
【エンジニアの独り言】
システムを「使う」時代のエンジニアに求められるもの(6月2日)
最新ハイテク講座
最新ハイテク講座
電気は家庭でつくる時代へ!燃料電池「エネファーム」(7月3日)
アクセス解析で見るWebマーケティング
アクセス解析で見るWebマーケティング
決定力を探るアクセス解析(7月3日)
百式のネットビジネス研究
百式のネットビジネス研究
ファーストフードを高級っぽく盛り付けて紹介している「Fancy Fast Food」(7月3日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(7月2日)
成約率、反応率を上げる Web 文章術
成約率、反応率を上げる Web 文章術
言葉がダイレクトにキャッシュを生む(7月2日)
不況時代の Web ビジネス最適化講座
不況時代の Web ビジネス最適化講座
アクセス解析エキスパートここだけの話、Web コンシェルジュの“勉強法”こっそり教えます(7月2日)
「Webからの脅威」―その傾向と最新対策
「Webからの脅威」―その傾向と最新対策
不正プログラムの分類(7月1日)
DevX
DevX
JavaScriptとDOMによる動的なWebページの作成(6月30日)
エンジニア転職ノウハウ開発室
エンジニア転職ノウハウ開発室
今のままで大丈夫?3匹の子ブタ的キャリア危険度診断(6月30日)
アイレップの SEM フロンティア
アイレップの SEM フロンティア
Web サイトは「無駄な穴のたくさん開いたじょうご」〜サイト成果向上の基本的な考え方(6月30日)
Copyright 2009 Japan Internet.com K.K. All Rights Reserved.http://www.internet.com/