亀の甲羅2

今日もまた朝とく起きて励まなん窓に明るきありあけの月

Windows環境におけるハッシュ(MD5)情報の取得について

Windows環境におけるハッシュ(MD5)情報の取得について

2つの環境におけるファイルの同一性を確認する方法として、簡易的にはタイムスタンプを用いてチェックしていた。 Gitを使うとcheckoutなど行うとワークツリーのファイルのタイムスタンプがカレント時刻になってしまうので、 タイムスタンプによるファイル同一性チェックは時代遅れだと理解した。

代替案としてハッシュによるファイル同一性のチェックを行うため、Windows環境におけるファイルのハッシュ値確認方法について調査した。

目次

本文

1. certutilコマンド(dos command)

dosコマンドなので、dosプロンプト(もう使わない方が良い)やWindows Terminalから実行する。

1.1 ヘルプ

> certutil -?   ・・・ヘルプ
> certutil -xxxx -?   ・・・動詞xxxxに関するヘルプ

1.2 使用方法

使用法:
CertUtil [オプション] -hashfile InFile [HashAlgorithm]
ファイルに暗号化ハッシュを生成し表示します

1.3 実行例

>certutil -hashfile C:\temp\aaa.txt MD5
MD5 ハッシュ (対象 C:\temp\aaa.txt):
dce6a8ae906b80be28661d223091430f
CertUtil: -hashfile コマンドは正常に完了しました。

ハッシュを得るにはすごく不便な(古い)コマンドのようだ。
正規表現指定やリカーシブに実行するオプションは見当たらない。
1ファイルずつ実行する必要があるようだ。

2. Get-FileHash コマンドレット(powershellコマンドレット)

Get-FileHashというコマンドレットがあったので、実行結果を下記に掲載する。

> Get-FileHash -Algorithm MD5 -Path C:\temp\aaa.txt

Algorithm       Hash                                                              Path
---------       ----                                                                   ----
MD5             DCE6A8AE906B80BE28661D223091430F       C:\temp\aaa.txt

powershellなので結果はオブジェクトとして取得でき、データへのアクセス性が高く使いやすい。
以下のようにオブジェクトのプロパティとしてHashのみにアクセスしたりできる。

> $a = Get-FileHash -Algorithm MD5 -Path C:\temp\aaa.txt
> $a.Hash
DCE6A8AE906B80BE28661D223091430F

Get-FileHashは*などのワイルドカード指定ができる。

PS C:\Users\hisabo> Get-FileHash -Algorithm MD5 -Path C:\temp\*

Algorithm       Hash                                                                   Path
---------       ----                                                                   ----
MD5             DCE6A8AE906B80BE28661D223091430F                                       C:\temp\aaa.txt
MD5             BDE942E67DEFC019BAE55B6DB8BD4195                                       C:\temp\AMPLog.log
MD5             7DDDF48D8BEF9FE4D910181D966855B2                                       C:\temp\cross.csv
MD5             7DDDF48D8BEF9FE4D910181D966855B2                                       C:\temp\crossjoin.csv
MD5             E9278ABDF45D9E7578EBAB6A0E523C2E                                       C:\temp\projects.csv
MD5             7B0236916EE5853B599A881BCBB53070                                       C:\temp\queries.csv
MD5             D41D8CD98F00B204E9800998ECF8427E                                       C:\temp\新しいビットマップ イメージ.bmp

しかし、リカーシブに走査するオプションは見当たらなかった。「-Recurse」オプションがあってもいいようなものだが。

3. Get-FileHash コマンドレットを使って再帰的走査(リカーシブ)

まあ、簡単ですよね。-Recurse がなくても同等のことは簡単にできる。
Get-ChildItemをリカーシブに走らせて、その結果をGet-FileHashに渡せばいい。

> Get-ChildItem -Recurse -Path "C:\temp\" | %{Get-FileHash -Algorithm MD5 $_.FullName} 

Algorithm       Hash                                                                   Path
---------       ----                                                                   ----
MD5             DCE6A8AE906B80BE28661D223091430F                                       C:\temp\aaa.txt
MD5             BDE942E67DEFC019BAE55B6DB8BD4195                                       C:\temp\AMPLog.log
MD5             7DDDF48D8BEF9FE4D910181D966855B2                                       C:\temp\cross.csv
MD5             7DDDF48D8BEF9FE4D910181D966855B2                                       C:\temp\crossjoin.csv
MD5             E9278ABDF45D9E7578EBAB6A0E523C2E                                       C:\temp\projects.csv
MD5             7B0236916EE5853B599A881BCBB53070                                       C:\temp\queries.csv
MD5             8691B38C64CB9629E470F86624A77CE0                                       C:\temp\ISL\PEXV\ImageInfo\2PB6G55RQ9ABQ.sfi
MD5             162CE879ADC99EFB4885E492A6E2FED9                                       C:\temp\ISL\PEXV\ImageInfo\4EMGNLWYW6KNY.sfi
MD5             D41D8CD98F00B204E9800998ECF8427E                                       C:\temp\test\aaa.txt
MD5             D41D8CD98F00B204E9800998ECF8427E                                       C:\temp\test\bbb.csv

 

4. certutilコマンドとGet-FileHash コマンドレットで得られるハッシュ値は同じなの?

ハッシュアルゴリズムMD5で同じなので、得られる結果は同じだと想定しているが念のため確認。

> certutil -hashfile C:\temp\aaa.txt MD5
MD5 ハッシュ (対象 C:\temp\aaa.txt):
dce6a8ae906b80be28661d223091430f
CertUtil: -hashfile コマンドは正常に完了しました。

> (Get-FileHash -Algorithm MD5 -Path C:\temp\aaa.txt).Hash
DCE6A8AE906B80BE28661D223091430F

ということで、同じ。大文字小文字の違いはあるけど。

command Hash value (MD5)
certutil dce6a8ae906b80be28661d223091430f
Get-FileHash DCE6A8AE906B80BE28661D223091430F

バージョン情報

> $PSVersionTable

Name                           Value                                                                                                          
----                           -----                                                                                                          
PSVersion                      5.1.19041.1023