回答:
コンテンツが文字列の場合:
$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
コメントで特定された最初のソリューションが提供する問題(ストリームを使用し、それを閉じ、大きなファイルをサポートする)を回避するため、これは確かに好ましいです。
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
ています。
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)))
これにより、メモリ使用量が少なくなり、2GBの制限がなくなります。
$stream = [System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
そして、$hash = [System.BitConverter]::ToString($md5.ComputeHash($stream))
その後、$stream.Close()
PowerShell Community Extensionsを使用している場合、これを簡単に実行するGet-Hashコマンドレットがあります。
C:\PS> "hello world" | Get-Hash -Algorithm MD5
Algorithm: MD5
Path :
HashString : E42B054623B3799CB71F0883900F2764
Get-FileHash
通常のPowerShell 4.0でコマンドレットを追加しました。VideのTechNetの。
以下は2行です。2行目で「hello」を変更してください。
PS C:\> [Reflection.Assembly]::LoadWithPartialName("System.Web")
PS C:\> [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("hello", "MD5")
以下は、相対パスと絶対パスを処理するために使用する関数です。
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に感謝します。
Dispose
呼び出しがでなければなりませんfinally
ブロック。
2003年までWindowsにデフォルトで長い間インストールされてきたもう1つの組み込みコマンドはCertutilです。これは、もちろんPowerShellからも呼び出すことができます。
CertUtil -hashfile file.foo MD5
(注意:堅牢性を最大にするために、MD5はすべて大文字にする必要があります)
FipsAlgorithmPolicy
が有効になっている場合に適したオプションです。
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
write-progress
ラインのバックティックは何をしますか?構文ハイライターはそれを好きではないようです。
このサイトには例があります: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()
受け入れられた答えで述べたように、Get-FileHash
ファイルで使用するのは簡単ですが、文字列で使用することも可能です:
$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))
非常に便利な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の公式ドキュメントからの抜粋です。ドキュメントには他の例があります。
MicrosoftからFile Checksum Integrity Verifier(FCIV)をダウンロードすると、これはワンライナーになります。
私はここからFCIVをダウンロードしました。 ファイルチェックサム整合性検証ユーティリティの可用性と説明
次のコマンドを実行します。チェックするファイルが10個ありました。
Get-ChildItem WTAM*.tar | % {.\fciv $_.Name}
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("-","")
SHA384
([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("-","")
これにより、リモートコンピューター上のファイルの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()
}
これは、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
これは、ダウンロードしたばかりのファイルの適切なチェックサムを計算し、それを元の公開されたチェックサムと比較する1行のコマンドの例です。
たとえば、Apache JMeterプロジェクトからのダウンロードの例を書きました。この場合、あなたは持っています:
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"
このコマンドを機能させるには、fileとfile.md5の両方が同じフォルダーにある必要があります。
これは、一貫したハッシュ値を取得するために使用するものです。
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()
}