「このファイル、本当に改ざんされていない?」
「ダウンロードしたファイルが公式と同じか確認したい」
そんなときに役立つのがハッシュ値のチェックです。
この記事では、Windows PowerShellを使って簡単にハッシュ値(SHA256やMD5など)を計算する方法を詳しく紹介します。セキュリティ対策やデータ管理の基本として、ぜひ覚えておきましょう。
そもそもハッシュ値とは?

ハッシュ値の基本概念
ハッシュ値(ダイジェスト値、チェックサムとも呼ばれる)は、ファイルの内容から一定の計算で求められる「指紋」のようなものです。
主な特徴:
- ファイルの内容が1ビットでも変われば、ハッシュ値も大きく変わる
- 同じファイルなら必ず同じハッシュ値になる
- ハッシュ値から元のファイルを復元することは不可能(一方向性)
- 計算が高速で、どんなサイズのファイルでも固定長の値になる
具体的な例で理解する
文字列での例
# "Hello World" という文字列のハッシュ値
$text1 = "Hello World"
$bytes1 = [System.Text.Encoding]::UTF8.GetBytes($text1)
$hash1 = [System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes1)
$hashString1 = [BitConverter]::ToString($hash1) -replace '-'
Write-Host $hashString1
# 結果: A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146E
# "Hello world" (小文字のw) という文字列のハッシュ値
$text2 = "Hello world"
$bytes2 = [System.Text.Encoding]::UTF8.GetBytes($text2)
$hash2 = [System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes2)
$hashString2 = [BitConverter]::ToString($hash2) -replace '-'
Write-Host $hashString2
# 結果: 64EC88CA00B268E5BA1A35678A1B5316D212F4F366B2477232534A8AECA37F3C
たった1文字の違い(大文字W→小文字w)で、ハッシュ値が完全に異なることがわかります。
ハッシュ値の実用的な用途
ファイルの整合性確認
- ダウンロードしたファイルが破損していないかチェック
- ネットワーク転送後のデータ整合性確認
- バックアップの正確性検証
セキュリティ用途
- ファイルの改ざん検知
- マルウェアの検出
- デジタル署名の基盤技術
システム管理
- 重複ファイルの検出
- ファイルバージョンの管理
- システムファイルの監視
PowerShellでハッシュ値を計算する基本方法
Get-FileHashコマンドレットの基本
PowerShellでは Get-FileHash
というコマンドレットを使えば、簡単にハッシュ値を計算できます。
最もシンプルな使い方
Get-FileHash C:\path\to\file.txt
実行結果の例:
Algorithm Hash Path
--------- ---- ----
SHA256 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92 C:\path\to\file.txt
結果の詳細説明
- Algorithm: 使用されたハッシュアルゴリズム
- Hash: 計算されたハッシュ値(16進数)
- Path: 対象ファイルのフルパス
アルゴリズムの指定
SHA256以外のアルゴリズムを使いたい場合は、-Algorithm
パラメータを使用します。
# MD5を使用
Get-FileHash C:\path\to\file.txt -Algorithm MD5
# SHA1を使用
Get-FileHash C:\path\to\file.txt -Algorithm SHA1
# SHA512を使用
Get-FileHash C:\path\to\file.txt -Algorithm SHA512
対応しているアルゴリズム一覧
アルゴリズム | ハッシュ長 | セキュリティレベル | 用途 |
---|---|---|---|
SHA256 | 256bit | 高 | 推奨(デフォルト) |
SHA512 | 512bit | 最高 | 高セキュリティ要求 |
SHA384 | 384bit | 高 | 中程度のセキュリティ |
SHA1 | 160bit | 低(非推奨) | 互換性のため |
MD5 | 128bit | 極低(非推奨) | 互換性のため |
セキュリティ上の注意:
- 推奨: SHA256, SHA512
- 非推奨: SHA1, MD5(脆弱性のため)
パフォーマンスの比較
# 大きなファイルでのパフォーマンステスト
$file = "C:\LargeFile.iso"
# 実行時間を測定
Measure-Command { Get-FileHash $file -Algorithm MD5 }
Measure-Command { Get-FileHash $file -Algorithm SHA1 }
Measure-Command { Get-FileHash $file -Algorithm SHA256 }
Measure-Command { Get-FileHash $file -Algorithm SHA512 }
一般的に、MD5 > SHA1 > SHA256 > SHA512の順で処理時間が長くなりますが、セキュリティとのバランスを考慮してSHA256の使用が推奨されます。
実践的なハッシュ値の活用方法

ファイルダウンロード時の検証
多くのソフトウェア配布サイトでは、ダウンロードファイルのハッシュ値を公開しています。
実際の検証手順
# 1. ダウンロードしたファイルのハッシュ値を計算
$downloadedFile = "C:\Downloads\software.exe"
$calculatedHash = Get-FileHash $downloadedFile -Algorithm SHA256
# 2. 公式サイトで公開されているハッシュ値
$officialHash = "8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92"
# 3. 比較して結果を表示
if ($calculatedHash.Hash -eq $officialHash) {
Write-Host "✓ ファイルは正常です(改ざんなし)" -ForegroundColor Green
} else {
Write-Host "✗ ファイルが改ざんされている可能性があります" -ForegroundColor Red
Write-Host "計算値: $($calculatedHash.Hash)"
Write-Host "公式値: $officialHash"
}
複数ファイルの一括処理
フォルダ内の全ファイルをチェック
# 基本的な一括処理
Get-ChildItem C:\ImportantData -File | ForEach-Object {
Get-FileHash $_.FullName -Algorithm SHA256
}
より詳細な情報付きの処理
# ファイル情報も含めた詳細レポート
Get-ChildItem C:\ImportantData -File -Recurse | ForEach-Object {
$hash = Get-FileHash $_.FullName -Algorithm SHA256
[PSCustomObject]@{
FileName = $_.Name
Path = $_.FullName
Size = $_.Length
LastModified = $_.LastWriteTime
SHA256 = $hash.Hash
}
} | Format-Table -AutoSize
CSVファイルへの出力と管理
ハッシュ値データベースの作成
# ハッシュ値をCSVで保存
$hashData = Get-ChildItem C:\ImportantData -File -Recurse | ForEach-Object {
$hash = Get-FileHash $_.FullName -Algorithm SHA256
[PSCustomObject]@{
RelativePath = $_.FullName.Replace("C:\ImportantData\", "")
FileName = $_.Name
FileSize = $_.Length
LastModified = $_.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")
SHA256Hash = $hash.Hash
CheckDate = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
}
}
# CSVに保存
$hashData | Export-Csv "C:\HashDatabase.csv" -NoTypeInformation -Encoding UTF8
Write-Host "$($hashData.Count) 件のファイルのハッシュ値を保存しました"
保存したハッシュ値との比較
# 以前に保存したハッシュ値と現在の値を比較
$previousHashes = Import-Csv "C:\HashDatabase.csv"
$changedFiles = @()
foreach ($record in $previousHashes) {
$currentPath = "C:\ImportantData\$($record.RelativePath)"
if (Test-Path $currentPath) {
$currentHash = Get-FileHash $currentPath -Algorithm SHA256
if ($currentHash.Hash -ne $record.SHA256Hash) {
$changedFiles += [PSCustomObject]@{
Path = $currentPath
FileName = $record.FileName
PreviousHash = $record.SHA256Hash
CurrentHash = $currentHash.Hash
LastModified = $record.LastModified
}
}
} else {
Write-Host "ファイルが削除されています: $currentPath" -ForegroundColor Yellow
}
}
if ($changedFiles.Count -gt 0) {
Write-Host "$($changedFiles.Count) 件のファイルが変更されています:" -ForegroundColor Red
$changedFiles | Format-Table -AutoSize
} else {
Write-Host "すべてのファイルに変更はありません" -ForegroundColor Green
}
高度なハッシュ値処理
ストリーミング処理による大容量ファイル対応
# 大容量ファイルのストリーミングハッシュ計算
function Get-StreamingFileHash {
param(
[string]$FilePath,
[string]$Algorithm = "SHA256"
)
try {
$hashAlgorithm = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
$fileStream = [System.IO.File]::OpenRead($FilePath)
$buffer = New-Object byte[] 4096
$totalBytes = 0
$fileLength = $fileStream.Length
while (($bytesRead = $fileStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$hashAlgorithm.TransformBlock($buffer, 0, $bytesRead, $null, 0) | Out-Null
$totalBytes += $bytesRead
# 進行状況を表示
$progress = [math]::Round(($totalBytes / $fileLength) * 100, 1)
Write-Progress -Activity "ハッシュ計算中" -Status "$progress% 完了" -PercentComplete $progress
}
$hashAlgorithm.TransformFinalBlock(@(), 0, 0) | Out-Null
$hash = [BitConverter]::ToString($hashAlgorithm.Hash) -replace '-'
return $hash
}
finally {
if ($fileStream) { $fileStream.Close() }
if ($hashAlgorithm) { $hashAlgorithm.Dispose() }
Write-Progress -Activity "ハッシュ計算中" -Completed
}
}
# 使用例
$hash = Get-StreamingFileHash "C:\VeryLargeFile.zip"
Write-Host "計算されたハッシュ値: $hash"
複数アルゴリズムの同時計算
# 複数のハッシュアルゴリズムで同時に計算
function Get-MultipleFileHash {
param([string]$FilePath)
$algorithms = @("MD5", "SHA1", "SHA256", "SHA512")
$results = @{}
foreach ($algorithm in $algorithms) {
try {
$hash = Get-FileHash $FilePath -Algorithm $algorithm
$results[$algorithm] = $hash.Hash
}
catch {
$results[$algorithm] = "エラー: $($_.Exception.Message)"
}
}
return [PSCustomObject]$results
}
# 使用例
$multiHash = Get-MultipleFileHash "C:\sample.txt"
$multiHash | Format-List
ネットワーク上のファイルのハッシュ計算
# ネットワーク共有上のファイルのハッシュ計算
function Get-NetworkFileHash {
param(
[string]$NetworkPath,
[string]$Algorithm = "SHA256",
[System.Management.Automation.PSCredential]$Credential
)
if ($Credential) {
# 認証情報を使用してネットワークドライブをマウント
$tempDrive = "Z:"
New-PSDrive -Name "Z" -PSProvider FileSystem -Root $NetworkPath -Credential $Credential
}
try {
$files = Get-ChildItem $NetworkPath -File
$results = @()
foreach ($file in $files) {
$hash = Get-FileHash $file.FullName -Algorithm $Algorithm
$results += [PSCustomObject]@{
FileName = $file.Name
Path = $file.FullName
Hash = $hash.Hash
Size = $file.Length
}
}
return $results
}
finally {
if ($Credential) {
Remove-PSDrive -Name "Z" -Force
}
}
}
セキュリティとベストプラクティス
ハッシュ値の保存と管理
セキュアな保存方法
# ハッシュ値をデジタル署名付きで保存
function Save-SecureHashDatabase {
param(
[string]$DataPath,
[string]$OutputPath,
[string]$CertificateThumbprint
)
# ハッシュ値を計算
$hashData = Get-ChildItem $DataPath -File -Recurse | ForEach-Object {
$hash = Get-FileHash $_.FullName -Algorithm SHA256
[PSCustomObject]@{
Path = $_.FullName
Hash = $hash.Hash
Timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
}
}
# JSONとして保存
$jsonData = $hashData | ConvertTo-Json -Depth 3
$jsonData | Out-File $OutputPath -Encoding UTF8
# デジタル署名を追加(証明書が利用可能な場合)
if ($CertificateThumbprint) {
Set-AuthenticodeSignature -FilePath $OutputPath -Certificate (Get-Item "Cert:\CurrentUser\My\$CertificateThumbprint")
}
}
ログ記録と監査
# ハッシュ値の変更をログに記録
function Start-FileIntegrityMonitoring {
param(
[string]$MonitorPath,
[string]$LogPath = "C:\FileIntegrityLog.txt"
)
# 初期ハッシュ値を記録
$baselineHashes = @{}
Get-ChildItem $MonitorPath -File -Recurse | ForEach-Object {
$hash = Get-FileHash $_.FullName -Algorithm SHA256
$baselineHashes[$_.FullName] = $hash.Hash
}
# 定期的なチェック(例:1時間ごと)
while ($true) {
Start-Sleep -Seconds 3600 # 1時間待機
$currentTime = Get-Date
Get-ChildItem $MonitorPath -File -Recurse | ForEach-Object {
$currentHash = Get-FileHash $_.FullName -Algorithm SHA256
if ($baselineHashes.ContainsKey($_.FullName)) {
if ($baselineHashes[$_.FullName] -ne $currentHash.Hash) {
$logEntry = "$currentTime : CHANGED - $($_.FullName)"
Add-Content -Path $LogPath -Value $logEntry
Write-Host "ファイル変更検出: $($_.FullName)" -ForegroundColor Yellow
# ベースラインを更新
$baselineHashes[$_.FullName] = $currentHash.Hash
}
} else {
# 新しいファイル
$logEntry = "$currentTime : NEW FILE - $($_.FullName)"
Add-Content -Path $LogPath -Value $logEntry
$baselineHashes[$_.FullName] = $currentHash.Hash
}
}
}
}
トラブルシューティングとエラー処理

よくあるエラーとその対処法
ファイルアクセス権限のエラー
# 安全なハッシュ計算(エラーハンドリング付き)
function Get-SafeFileHash {
param(
[string]$FilePath,
[string]$Algorithm = "SHA256"
)
try {
# ファイルの存在確認
if (-not (Test-Path $FilePath)) {
throw "ファイルが見つかりません: $FilePath"
}
# アクセス権限の確認
$acl = Get-Acl $FilePath
if (-not $acl) {
throw "ファイルにアクセスできません: $FilePath"
}
# ハッシュ値を計算
$hash = Get-FileHash $FilePath -Algorithm $Algorithm -ErrorAction Stop
return [PSCustomObject]@{
Path = $FilePath
Algorithm = $Algorithm
Hash = $hash.Hash
Status = "成功"
Error = $null
}
}
catch {
return [PSCustomObject]@{
Path = $FilePath
Algorithm = $Algorithm
Hash = $null
Status = "エラー"
Error = $_.Exception.Message
}
}
}
# 使用例
$result = Get-SafeFileHash "C:\ProtectedFile.txt"
if ($result.Status -eq "成功") {
Write-Host "ハッシュ値: $($result.Hash)"
} else {
Write-Host "エラー: $($result.Error)" -ForegroundColor Red
}
大容量ファイルでのメモリ不足
# メモリ効率を考慮したハッシュ計算
function Get-MemoryEfficientHash {
param(
[string]$FilePath,
[string]$Algorithm = "SHA256",
[int]$BufferSize = 1MB
)
try {
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
$stream = [System.IO.File]::OpenRead($FilePath)
$buffer = New-Object byte[] $BufferSize
$totalRead = 0
$fileSize = $stream.Length
while (($bytesRead = $stream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$hasher.TransformBlock($buffer, 0, $bytesRead, $null, 0) | Out-Null
$totalRead += $bytesRead
# 進行状況の表示とメモリ管理
if ($totalRead % (10 * $BufferSize) -eq 0) {
$percent = [math]::Round(($totalRead / $fileSize) * 100, 1)
Write-Progress -Activity "ハッシュ計算" -PercentComplete $percent
[System.GC]::Collect() # ガベージコレクションを強制実行
}
}
$hasher.TransformFinalBlock(@(), 0, 0) | Out-Null
$hashBytes = $hasher.Hash
$hashString = [BitConverter]::ToString($hashBytes) -replace '-'
return $hashString
}
finally {
if ($stream) { $stream.Close() }
if ($hasher) { $hasher.Dispose() }
Write-Progress -Activity "ハッシュ計算" -Completed
[System.GC]::Collect()
}
}
まとめ
Windows PowerShellを使ったハッシュ値の計算と活用について、包括的に解説しました。
主要なポイント
基本操作:
Get-FileHash
で簡単にハッシュ値を計算- SHA256, SHA512, MD5 など用途に応じてアルゴリズムを選択
- フォルダ単位での一括計算やCSV出力も可能
実用的な活用:
- ファイルダウンロード時の整合性確認
- 改ざん検知とセキュリティ監視
- データバックアップの検証
- 重複ファイルの検出
高度な機能:
- 大容量ファイルのストリーミング処理
- 複数アルゴリズムでの同時計算
- ネットワークファイルのハッシュ計算
- セキュアな保存と監査ログ
セキュリティの観点
推奨事項:
- SHA256以上のアルゴリズムを使用
- ハッシュ値の定期的な確認
- 変更の記録と追跡
- セキュアな保存方法の採用
注意事項:
- MD5やSHA1は脆弱性があるため避ける
- ハッシュ値自体の改ざんにも注意
- 重要なデータは複数の手法で検証
コメント