2つのファイルが本当に同じか確認する ― PowerShellでSHA-256を使う

PowerShellカテゴリを表すパンダのイラスト PowerShell

この記事について
この記事は、Microsoft LearnとNISTの公開資料を確認して整理しています。

検証ステータス:📘 公式仕様確認済み・Windows実機未確認
掲載コードはPowerShell向けです。実機確認前なので「コピペ実行確認済み」とはしていません。

2つのファイルの中身が同じか確認したいなら、PowerShellの Get-FileHash でSHA-256を計算し、ハッシュ値を比較する方法が分かりやすいです。ファイル名や更新日時ではなく、内容から計算した値を比較できます。

最小の比較

$hashA = (Get-FileHash -LiteralPath '.\fileA.bin' -Algorithm SHA256).Hash
$hashB = (Get-FileHash -LiteralPath '.\fileB.bin' -Algorithm SHA256).Hash

$hashA -eq $hashB

TrueならSHA-256が一致、Falseなら一致していません。

flowchart LR
    A[File A] --> C[SHA-256]
    B[File B] --> D[SHA-256]
    C --> E{Digestを比較}
    D --> E
    E -->|一致| F[同一内容の確認に使う]
    E -->|不一致| G[内容は異なる]

Microsoft Learnでは、Get-FileHashの既定アルゴリズムはSHA256です。

ダミーファイルを作って確かめる

Set-Content -LiteralPath '.\fileA.txt' -Value 'papanda925 sample' -NoNewline
Copy-Item -LiteralPath '.\fileA.txt' -Destination '.\fileB.txt'

Get-FileHash -LiteralPath '.\fileA.txt' -Algorithm SHA256
Get-FileHash -LiteralPath '.\fileB.txt' -Algorithm SHA256

fileBはfileAのコピーなので、内容が変わっていなければハッシュ値も一致します。

次に1文字だけ変えます。

Set-Content -LiteralPath '.\fileB.txt' -Value 'papanda925 Sample' -NoNewline

(Get-FileHash '.\fileA.txt').Hash
(Get-FileHash '.\fileB.txt').Hash

入力が少し変わるだけで、ハッシュ値は大きく変わります。

flowchart TB
    A["papanda925 sample"] --> B[SHA-256]
    C["papanda925 Sample"] --> D[SHA-256]
    B --> E[Digest A]
    D --> F[Digest B]
    E -. 入力が1文字違う .-> F

サイズが同じでも中身は同じとは限らない

次の2つは同じ長さですが、内容は違います。

ABCDEF
123456

ファイルサイズは「明らかに違うファイルを早く見つける」には便利ですが、内容比較の代わりにはなりません。

実用コードでは存在確認も入れる

$pathA = '.\fileA.txt'
$pathB = '.\fileB.txt'

foreach ($path in @($pathA, $pathB)) {
    if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
        throw "File not found: $path"
    }
}

$a = Get-FileHash -LiteralPath $pathA -Algorithm SHA256
$b = Get-FileHash -LiteralPath $pathB -Algorithm SHA256

[pscustomobject]@{
    FileA = $a.Path
    FileB = $b.Path
    HashA = $a.Hash
    HashB = $b.Hash
    Same  = ($a.Hash -eq $b.Hash)
}

「存在しないファイルを比較したのに、後続処理が成功したように見える」という状態を避けるため、先に入力を確認します。

ダウンロードしたファイルの確認にも使える

配布元がSHA-256値を公開している場合は、自分がダウンロードしたファイルの値と比較できます。

Get-FileHash -LiteralPath '.\download.iso' -Algorithm SHA256

重要なのは「自分で計算した2つの値」を比べるだけでなく、信頼できる配布元が別経路で公開している期待値と照合する使い方です。

SHA-256とcollision

暗号学的ハッシュには、異なる入力が同じ値になるcollisionという概念があります。したがって、数学的な意味で「同じハッシュなら絶対に同じ」と説明するのは厳密ではありません。

一方、通常のファイル整合性確認ではSHA-256は広く使われています。Microsoft LearnもGet-FileHashの既定値をSHA256としており、MD5やSHA1は攻撃に対して安全とは見なされないと説明しています。

ハッシュは暗号化ではない

SHA-256はファイルを秘密にする処理ではありません。

flowchart LR
    A[ファイル内容] --> B[SHA-256]
    B --> C[固定長のdigest]
    C -. 元ファイルを暗号化しているわけではない .-> D[秘密保持とは別]

整合性確認と暗号化は目的が異なります。

まとめ

  • Get-FileHashでファイル内容からSHA-256を計算できる

  • ファイル名・日時・サイズだけより内容比較に向いている

  • 1文字の変更でもハッシュ値は変化する

  • 配布元が公開したSHA-256との照合にも使える

  • SHA-256は秘密保持のための暗号化ではない

公式情報・一次情報

Microsoft Learn — Get-FileHash
https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/get-filehash

NIST — Secure Hash Standard (SHS)
https://csrc.nist.gov/pubs/fips/180-4/upd1/final

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました