バイナリファイルのMD5を自前で算出するには?

解決


かなもの  2004-06-30 14:13:30  No: 9694

以前、この掲示板にお世話になりましたかなものと申します。
今回、どうしても解らない事がありまして、ご質問させて頂きます。

ファイルの改ざんをあらかじめ防止するには、
CRCなどをチェックして監視するというのがあると思います。

それを自前でやりたいと思いまして、いろいろ調べてみたのですが、
NET上でも手元にある書籍でも、見つける事が出来ませんでした。

唯一見つけた有力な情報は
http://forum.nifty.com/fdelphi/samples/01242.html
コレのみでした。
この参考サイトの情報は、テキストの文字をMD5を算出するもので、
実際にTESTを行い、テキストはMD5にする事が出来ました。

しかし、今回行いたい事は、EXEなどの実行ファイル、
つまりバイナリファイルのMD5算出なのです。

この情報を、どう活用すれば良いのか?すら、
自分には探し出すことが出来ませんでした。

試しにダメ元で、バイナリファイルの16進数のDATAを、Stringに集めて出してみましたが、
本来の数値とはかけ離れたものでした。
又、Stringに集めてる為か、時間がかかります。

本来はすぐに算出出来るはずなんですよね…。

ご回答のほど、よろしくお願いします。

環境
Delphi6 Personal
WindowsXP SP1


にしの  2004-06-30 19:01:06  No: 9695

http://hp.vector.co.jp/authors/VA008160/cipher/dec.htm
こちらに、コンポーネントが紹介されています。

それと、
http://forum.nifty.com/fdelphi/samples/01242.html
にあるコードでは、わざわざ文字列(String)をcharへのポインタ(PCHAR)に返還し、さらにByteのポインタ(PByte)に返還しているように見えるのですが。
となると、
文字列->Byte配列
とやっているところを、
Byte配列->文字列->Byte配列
とやっているということでしょうか。
ふつうに渡せばいいのでは?


HPW  2004-06-30 19:20:13  No: 9696

>試しにダメ元で、バイナリファイルの16進数のDATAを、Stringに集めて出してみましたが、
>本来の数値とはかけ離れたものでした。
>又、Stringに集めてる為か、時間がかかります。

オジャマ : 「"Stringに集めて"ってどうやったんでしょうね〜」
ピーマコ : 「時間がかかったって言ってるんで、Copy関数使ったとか?」
オジャマ : 「どうやっても〜、MD5Update関数の引数は PChar型なんで、バイナリを分割して、それをString型で渡すのはマズイでしょ〜^^;」
ピーマコ : 「えっ、そうなの?どして?」
オジャマ : 「チョット前にもあったでしょ^^…例の #0ですよ」
ピーマコ : 「あ〜っ、そうそう、#0 ね。じゃぁバイナリを文字列にして渡すのはダメかぁ。どうする〜?」
なかざわ : 「二人とも どこ見とるンや。眼フシアナかい」
ピーマコ : 「え〜、この可愛い瞳は視力1.5ですヨ〜」
なかざわ : 「ンならよ〜く見てみぃ。そのサイト、バイナリファイルのMD5作成も解説しとるやん」
ピーマコ : 「な〜んだ、ならもっと早く言ってくださいよぉ。ホント意地悪ばぁ〜…あっ、ぃゃぃゃ^^;…お姐さまのイジワル〜♪」
なかざわ : 「なんやて、いま何言うた!?イジワルばぁさん?」
ピーマコ : 「いぇいぇ、そんなこと…めっそうもない…^^;;」


かなもの  2004-07-01 01:53:17  No: 9697

ご回答ありがとう御座います。

・にしのさん
> 文字列->Byte配列
> とやっているところを、
> Byte配列->文字列->Byte配列
> とやっているということでしょうか。
> ふつうに渡せばいいのでは?
これは、単純に自分の理解不足です。
仕組みが理解出来ていないのですが、
何もせずに質問するのも失礼ですし、
とりあえず何かしないと…と思って試したわけです。
「Byte配列を渡す」という内容を理解していない事が原因のようです。

コンポーネントがあるという事なので、帰宅したら早速試してみたいと思います。

・HPWさん
上記の通り、仕組みを理解していないので、無茶な事をしてました。
参考サイトですが、自分の知識範囲外の解説などがありましたが、
とにかくまずは動かしてみるという事をしました。
ですが、不明な点が多数ありましたので、今回質問させて頂いたわけです。
> MD5Update関数の引数は PChar型なんで、バイナリを分割して、それをString型で渡すのはマズイ
大変申し訳ないのですが、ここが理解出来ていません。
過去ログに何か書かれているようですので、時間を見て参照したいと思います。

今回のお答えを頂いた結果は、追ってご報告したいと思います。


かなもの  2004-07-01 02:37:11  No: 9698

補足です。

> そのサイト、バイナリファイルのMD5作成も解説しとるやん
申し訳ないですが、どこに書かれているのか解りませんでした。

あと、お恥ずかしいながら、バイナリファイルを
「どうやって読み込んで渡すのか?」の時点で詰まってます。

意味も解らず試した内容が

ragexehash : Array of Byte;
FH ,i ,s : Integer;

SetLength(ragexehash,i);
for i := 0 to i do
begin
Application.ProcessMessages;
FileRead(FH,ragexehash[i],Sizeof(Byte));
s := ragexehash[i];
str := str + IntToHex(s,2);
end;

です。全く方向性が違うと思います。

もう一度、根本的な部分からNETで調べなおしてみたいと思います。


HPW  2004-07-01 17:59:24  No: 9699

オジャマ : 「ワタシ、安くて美味しいお店みつけたんですよ。今日のお昼一緒にどうですか〜?」
ピーマコ : 「わ〜行きたい♪おごってくれる?」
オジャマ : 「ダメですよ。ワタシだってギリギリなんですから〜」
ピーマコ : 「あ゛〜、イジワルばぁ〜さんがお休みでなかったら おごってもらえるのにな〜」
オジャマ : 「またそんなヒドイこと言って〜^^;…もしナカザワさんがいたらまた怒鳴られますよ」
ピーマコ : 「ハハハ^^;つい口癖で出ちゃうのよネ。それじゃオニのイヌまにカンガル〜♪」
オジャマ : 「それって…なにかチワワような〜…」

const
  BufferSize = $400;
var
  Buffer : array[0..BufferSize]of Byte;
  .....
begin
 Stream := TFileStream.Create('ほにゃらら.exe', fmOpenRead);
 try
>  // 大きなデータを分割しながら“要約”を作成する場合には、
>  Stream.Position := 0;
>  MD5Init(ctx);
>  while TRUE do
>  begin
>   DataSize := Stream.Read(Buffer, BufferSize);
>   if DataSize = 0 then break;
>   MD5Update(ctx, @Buffer, DataSize);
>  end;
>  MD5Final(ctx, digest);
>  // のように使います。

>  // 16進数の文字列に変換
>  Result := '';
>  for i := 0 to 15 do
>   Result := Result + LowerCase(IntToHex(BYTE(digest[i]), 2));
 finally
  Stream.Free;
 end;
end;


かなもの  2004-07-05 19:57:17  No: 9700

お返事が遅れてしまいました。かなものです。

・HPWさん
上記内容を、そのままではありますが、
コピーして動きました。ありがとう御座います。

まだ内容を把握しておらず、ブラックボックス状態ですが・・・
参考ソースを頂けるのは、本当にありがたいです。
時間を見て、内容を調べてみたいと思います。

又、コンポーネントですが、まだ上手く動かす事ができません。
こちらの方が高性能のようですので、
可能であればコンポーネント、ダメだったらこちらを使いたいと思います。

ありがとうございました。

この掲示板には、多くの問題の道しるべをして頂いて、
本当に助けられています。感謝感謝です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加