PowerShellでMD5チェックサムを取得する方法


179

一部のコンテンツのMD5チェックサムを計算したいと思います。PowerShellでこれを行うにはどうすればよいですか?


3
「一部のコンテンツ」とは何ですか?ファイル?ストリング?
vcsjones

回答:


326

コンテンツが文字列の場合:

$someString = "Hello, World!"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = New-Object -TypeName System.Text.UTF8Encoding
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($someString)))

コンテンツがファイルの場合:

$someFilePath = "C:\foo.txt"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))

PowerShellバージョン4以降では、Get-FileHashコマンドレットを使用することで、すぐに使用できるファイルを簡単に作成できます。

Get-FileHash <filepath> -Algorithm MD5

コメントで特定された最初のソリューションが提供する問題(ストリームを使用し、それを閉じ、大きなファイルをサポートする)を回避するため、これは確かに好ましいです。


12
Exception calling "ReadAllBytes" with "1" argument(s): "The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size."Powershellを初めて使用するLinuxの人として、私はmd5の合計を取得するのに苦労していることに非常に不満を感じmd5sum file.extています。
StockB 2013

@StockBキースの以下の答えは、おそらくこれをよりうまく処理するでしょう。私は同意します、powershellにはいくつかの欠点があります。
vcsjones 2013

5
私は拡張機能のないPowerShellをインストールしているので、故障してコマンドラインのmd5sumクローンをダウンロードしました。マイクロソフトのものが好きになりたいのですが、好きではありません。
StockB 2013

23
@StockB vcsjonesのメソッドはバッファリングされません... =大きなファイルに非常にメモリを要求します。ストリームを使用することをお勧めします。$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)))これにより、メモリ使用量少なくなり、2GBの制限がなくなります
Davor Josipovic 2013

20
@davorは、ストリームを不確定な期間開いたままにするため、Powershellが閉じられるまでファイルを削除できません。 $stream = [System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)そして、$hash = [System.BitConverter]::ToString($md5.ComputeHash($stream))その後、$stream.Close()
ジョーAmenta

57

PowerShell Community Extensionsを使用している場合、これを簡単に実行するGet-Hashコマンドレットがあります。

C:\PS> "hello world" | Get-Hash -Algorithm MD5


Algorithm: MD5


Path       :
HashString : E42B054623B3799CB71F0883900F2764

10
Get-HashはPowerShell Community Extensionsから提供されています。パッケージを使用できない、または使用しない場合、彼らはGet-FileHash通常のPowerShell 4.0でコマンドレットを追加しました。VideのTechNetの
TomaszCudziło2014

これ(そしておそらくほとんどのPSソリューション)は文字列をUTF-16(リトルエンディアン?)としてエンコードすることに注意してください。
クリスチャンマン2017年

PowerShell Community Extensionsへのリンクは、CodePlexアーカイブにリダイレクトされます(CodePlexは2017年に閉鎖されました)。おそらくGitHubに変更しますか?(GitHubの新しいマスターの場所ですか?)
Peter Mortensen

16

以下は2行です。2行目で「hello」を変更してください。

PS C:\> [Reflection.Assembly]::LoadWithPartialName("System.Web")
PS C:\> [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("hello", "MD5")

1
この結果は、受け入れられた回答で得られる出力とは異なります。これは、文字列「hello」のハッシュを計算します。「hello」を置き換えるパスによって定義されるファイルではなく、正しいですか?
RobertG 2014年

1
確かに、しかしOPはファイルを要求しなかったので、文字列の解決策を探してここに来ました
Chris F Carroll

16

以下は、相対パスと絶対パスを処理するために使用する関数です。

function md5hash($path)
{
    $fullPath = Resolve-Path $path
    $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $file = [System.IO.File]::Open($fullPath,[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
    try {
        [System.BitConverter]::ToString($md5.ComputeHash($file))
    } finally {
        $file.Dispose()
    }
}

ReadAllBytes()の代わりにOpen()を使用するよう提案する上記の@davorと、finallyブロックを使用するよう提案する@ jpmc26に感謝します。


2
このアプローチはvcsjonesやKeithよりも優れており、2GBを超えるファイルを入力でき、拡張機能やPowerShell 4.0を必要としません。
Chirag Bhatia-chirag64 2014年

1
Dispose呼び出しがでなければなりませんfinallyブロック。
jpmc26

12

2003年までWindowsにデフォルトで長い間インストールされてきたもう1つの組み込みコマンドはCertutilです。これは、もちろんPowerShellからも呼び出すことができます。

CertUtil -hashfile file.foo MD5

(注意:堅牢性を最大にするために、MD5はすべて大文字にする必要があります)


1
これは、FipsAlgorithmPolicyが有効になっている場合に適したオプションです。
ウィリアムジョンホールデン

9

ComputeHash()を使用したオンラインの例はたくさんあります。私のテストでは、ネットワーク接続を介して実行すると、これが非常に遅いことがわかりました。以下のスニペットは私にとってははるかに高速に実行されますが、走行距離は異なる場合があります。

$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
$fd = [System.IO.File]::OpenRead($file)
$buf = New-Object byte[] (1024*1024*8) # 8 MB buffer
while (($read_len = $fd.Read($buf,0,$buf.length)) -eq $buf.length){
    $total += $buf.length
    $md5.TransformBlock($buf,$offset,$buf.length,$buf,$offset)
    Write-Progress -Activity "Hashing File" `
       -Status $file -percentComplete ($total/$fd.length * 100)
}

# Finalize the last read
$md5.TransformFinalBlock($buf, 0, $read_len)
$hash = $md5.Hash

# Convert hash bytes to a hexadecimal formatted string
$hash | foreach { $hash_txt += $_.ToString("x2") }
Write-Host $hash_txt

1
あなたの方法は他の答えからのReadAllBytesの2G​​b制限を克服します、それはまさに私が必要としたものです。
ジェイ

write-progressラインのバックティックは何をしますか?構文ハイライターはそれを好きではないようです。
mwfearnley 2017

1
@mwfearnleyバックティックは行の継続を可能にします。blogs.technet.microsoft.com/heyscriptingguy/2015/06/19/...
cmcginty

6

このサイトには例があります:MD5チェックサムにPowershellを使用する。.NETフレームワークを使用してMD5ハッシュアルゴリズムのインスタンスをインスタンス化し、ハッシュを計算します。

以下は、スティーブンのコメントを組み込んだ記事のコードです。

param
(
  $file
)

$algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5")
$stream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open,
    [System.IO.FileAccess]::Read)

$md5StringBuilder = New-Object System.Text.StringBuilder
$algo.ComputeHash($stream) | % { [void] $md5StringBuilder.Append($_.ToString("x2")) }
$md5StringBuilder.ToString()

$stream.Dispose()

1
読み取り専用ファイルでは機能しないことを除いて、良いです!$ stream = New-Object System.IO.FileStream($ Path、[System.IO.FileMode] :: Open、[System.IO.FileAccess] :: Read)が必要です
Stephen Connolly

1
リンクが途絶えると、答えはまったく役に立たなくなります。stackoverflow.com/help/how-to-answer
モニカと一緒に

1
私があなたの反対票であると私が思うことに応じて、私はここの記事からコードを切り取って貼り付けました。それは盗作だと感じたので、去年はそれをしませんでした。スティーブンの読み取り専用の適応を追加すると、投稿する価値があると感じました。
ネオタピル2013年

@neontapir言うだけで:何かを逐語的に(または修正を加えて)投稿することは、ソースを認めない場合の盗作にすぎません。著作権(法的または道徳的)は別の問題ですが、ほとんどのコードスニペットではそれについて心配する傾向はありません。
mwfearnley

6

受け入れられた答えで述べたように、Get-FileHashファイルで使用するのは簡単ですが、文字列で使用することも可能です:

$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))

5

非常に便利なGet-FileHash関数が追加されました。

PS C:\> Get-FileHash C:\Users\Andris\Downloads\Contoso8_1_ENT.iso -Algorithm SHA384 | Format-List

Algorithm : SHA384
Hash      : 20AB1C2EE19FC96A7C66E33917D191A24E3CE9DAC99DB7C786ACCE31E559144FEAFC695C58E508E2EBBC9D3C96F21FA3
Path      : C:\Users\Andris\Downloads\Contoso8_1_ENT.iso

に変更SHA384してくださいMD5

この例は、PowerShell 5.1の公式ドキュメントからの抜粋です。ドキュメントには他の例があります。



3

PowerShellワンライナー(ハッシュする文字列)

MD5

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA1

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA256

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA3​​84

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA512

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

1

これにより、リモートコンピューター上のファイルのMD5ハッシュが返されます。

Invoke-Command -ComputerName RemoteComputerName -ScriptBlock {
    $fullPath = Resolve-Path 'c:\Program Files\Internet Explorer\iexplore.exe'
    $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $file = [System.IO.File]::OpenRead($fullPath)
    $hash = [System.BitConverter]::ToString($md5.ComputeHash($file))
    $hash -replace "-", ""
    $file.Dispose()
}

1

右クリックメニューオプションのサンプル:

[HKEY_CLASSES_ROOT\*\shell\SHA1 PS check\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Get-FileHash -Algorithm SHA1 '%1'"

0

これは、SHA256フィンガープリントを検証しようとするきれいな印刷例です。PowerShell v4を使用してgpg4win v3.0.3をダウンロードしました(必須Get-FileHash)。

https://www.gpg4win.org/download.htmlからパッケージをダウンロードし、PowerShellを開き、ダウンロードページからハッシュを取得して実行します。

cd ${env:USERPROFILE}\Downloads
$file = "gpg4win-3.0.3.exe"

# Set $hash to the hash reference from the download page:
$hash = "477f56212ee60cc74e0c5e5cc526cec52a069abff485c89c2d57d1b4b6a54971"

# If you have an MD5 hash: # $hashAlgo="MD5"
$hashAlgo = "SHA256"

$computed_hash = (Get-FileHash -Algorithm $hashAlgo $file).Hash.ToUpper()
if ($computed_hash.CompareTo($hash.ToUpper()) -eq 0 ) {
    Write-Output "Hash matches for file $file" 
} 
else { 
    Write-Output ("Hash DOES NOT match for file {0}: `nOriginal hash: {1} `nComputed hash: {2}" -f ($file, $hash.ToUpper(), $computed_hash)) 
}

出力:

Hash matches for file gpg4win-3.0.3.exe

0

これは、ダウンロードしたばかりのファイルの適切なチェックサムを計算し、それを元の公開されたチェックサムと比較する1行のコマンドの例です。

たとえば、Apache JMeterプロジェクトからのダウンロードの例を書きました。この場合、あなたは持っています:

  1. ダウンロードしたバイナリファイル
  2. 次の形式の1つの文字列としてfile.md5に発行されたオリジナルのチェックサム:

3a84491f10fb7b147101cf3926c4a855 * apache-jmeter-4.0.zip

次に、このPowerShellコマンドを使用して、ダウンロードしたファイルの整合性を確認できます。

PS C:\Distr> (Get-FileHash .\apache-jmeter-4.0.zip -Algorithm MD5).Hash -eq (Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash")

出力:

True

説明:

-eq演算子の最初のオペランドは、ファイルのチェックサムを計算した結果です。

(Get-FileHash .\apache-jmeter-4.0.zip -Algorithm MD5).Hash

2番目のオペランドは、公開されたチェックサム値です。最初に1つの文字列であるfile.md5のコンテンツを取得し、次に文字列形式に基づいてハッシュ値を抽出します。

Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash"

このコマンドを機能させるには、filefile.md5の両方が同じフォルダーにある必要があります。


0

これは、一貫したハッシュ値を取得するために使用するものです。

function New-CrcTable {
    [uint32]$c = $null
    $crcTable = New-Object 'System.Uint32[]' 256

    for ($n = 0; $n -lt 256; $n++) {
        $c = [uint32]$n
        for ($k = 0; $k -lt 8; $k++) {
            if ($c -band 1) {
                $c = (0xEDB88320 -bxor ($c -shr 1))
            }
            else {
                $c = ($c -shr 1)
            }
        }
        $crcTable[$n] = $c
    }

    Write-Output $crcTable
}

function Update-Crc ([uint32]$crc, [byte[]]$buffer, [int]$length, $crcTable) {
    [uint32]$c = $crc

    for ($n = 0; $n -lt $length; $n++) {
        $c = ($crcTable[($c -bxor $buffer[$n]) -band 0xFF]) -bxor ($c -shr 8)
    }

    Write-Output $c
}

function Get-CRC32 {
    <#
        .SYNOPSIS
            Calculate CRC.
        .DESCRIPTION
            This function calculates the CRC of the input data using the CRC32 algorithm.
        .EXAMPLE
            Get-CRC32 $data
        .EXAMPLE
            $data | Get-CRC32
        .NOTES
            C to PowerShell conversion based on code in https://www.w3.org/TR/PNG/#D-CRCAppendix

            Author: Øyvind Kallstad
            Date: 06.02.2017
            Version: 1.0
        .INPUTS
            byte[]
        .OUTPUTS
            uint32
        .LINK
            https://communary.net/
        .LINK
            https://www.w3.org/TR/PNG/#D-CRCAppendix

    #>
    [CmdletBinding()]
    param (
        # Array of Bytes to use for CRC calculation
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [byte[]]$InputObject
    )

    $dataArray = @()
    $crcTable = New-CrcTable
    foreach ($item  in $InputObject) {
        $dataArray += $item
    }
    $inputLength = $dataArray.Length
    Write-Output ((Update-Crc -crc 0xffffffffL -buffer $dataArray -length $inputLength -crcTable $crcTable) -bxor 0xffffffffL)
}

function GetHash() {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$InputString
    )

    $bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)
    $hasCode = Get-CRC32 $bytes
    $hex = "{0:x}" -f $hasCode
    return $hex
}

function Get-FolderHash {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$FolderPath
    )

    $FolderContent = New-Object System.Collections.ArrayList
    Get-ChildItem $FolderPath -Recurse | Where-Object {
        if ([System.IO.File]::Exists($_)) {
            $FolderContent.AddRange([System.IO.File]::ReadAllBytes($_)) | Out-Null
        }
    }

    $hasCode = Get-CRC32 $FolderContent
    $hex = "{0:x}" -f $hasCode
    return $hex.Substring(0, 8).ToLower()
}

PowerShellコードをどこからコピーしましたか?https://communary.net/
Peter Mortensen

0

以下は、特定の文字列のMD5を取得するために使用しているスニペットです。

$text = "text goes here..."
$md5  = [Security.Cryptography.MD5CryptoServiceProvider]::new()
$utf8 = [Text.UTF8Encoding]::UTF8
$bytes= $md5.ComputeHash($utf8.GetBytes($text))
$hash = [string]::Concat($bytes.foreach{$_.ToString("x2")}) 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.