如何在 PowerShell 中获取 MD5 校验和
Posted
技术标签:
【中文标题】如何在 PowerShell 中获取 MD5 校验和【英文标题】:How to get an MD5 checksum in PowerShell 【发布时间】:2012-05-18 06:16:59 【问题描述】:我想计算一些内容的MD5 校验和。如何在 PowerShell 中执行此操作?
【问题讨论】:
什么是“一些内容”?一份文件?字符串? 【参考方案1】:从 PowerShell 版本 4 开始,使用 Get-FileHash
cmdlet 可以轻松处理开箱即用的文件:
Get-FileHash <filepath> -Algorithm MD5
这当然是更可取的,因为它避免了旧 PowerShell 解决方案在 cmets 中确定的问题(使用流、关闭它并支持大文件)。
如果内容是字符串:
$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)))
对于旧 PowerShell 版本
如果内容是文件:
$someFilePath = "C:\foo.txt"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
【讨论】:
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 总和时遇到的困难感到非常恼火,这在 Linux 上只是 md5sum file.ext
。
@StockB Keith 下面的回答可能会更好地处理这个问题。我同意,powershell 有一些缺点。
我安装了没有扩展的 vanilla PowerShell,所以我崩溃并下载了一个命令行 md5sum 克隆,效果很好。我想喜欢微软的东西,但我就是不能。
@StockB vcsjones 的方法没有缓冲... = 对大文件的内存要求很高。我建议您使用流:$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)))
这使您内存使用率低并且没有 2GB 限制。
@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()
【参考方案2】:
如果您使用的是PowerShell Community Extensions,则有一个 Get-Hash 命令行开关可以轻松完成此操作:
C:\PS> "hello world" | Get-Hash -Algorithm MD5
Algorithm: MD5
Path :
HashString : E42B054623B3799CB71F0883900F2764
【讨论】:
Get-Hash 来自 PowerShell 社区扩展。当您不能或不会使用该软件包时,他们会在 vanilla PowerShell 4.0 中添加一个 cmdletGet-FileHash
。视频TechNet.
请注意,这(可能是大多数 PS 解决方案)将字符串编码为 UTF-16(小端?)。
PowerShell 社区扩展的链接重定向到 CodePlex 存档(CodePlex 于 2017 年关闭)。也许改成GitHub one? (新的 master 位置在 GitHub 上吗?)【参考方案3】:
这是我使用的处理相对路径和绝对路径的函数:
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()
感谢上面的 @davor 建议使用 Open() 而不是 ReadAllBytes() 并感谢 @jpmc26 建议使用 finally 块。
【讨论】:
恕我直言,这种方法比 vcsjones 和 Keith 更好,因为它可以输入大于 2GB 的文件,并且不需要任何扩展或 PowerShell 4.0。Dispose
调用应该在 finally
块中。【参考方案4】:
这里是两行,把第2行的“hello”改一下:
PS C:\> [Reflection.Assembly]::LoadWithPartialName("System.Web")
PS C:\> [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("hello", "MD5")
【讨论】:
这个结果不等于我接受的答案得到的输出。它计算字符串“hello”的哈希,而不是由我替换“hello”的任何路径定义的文件的哈希,对吗? 是的,但是OP没有要求文件,我来这里寻找字符串解决方案【参考方案5】:另一个早在 2003 年就默认安装在 Windows 中的内置命令是 Certutil,当然也可以从 PowerShell 调用。
CertUtil -hashfile file.foo MD5
(警告:MD5 应全部大写以实现最大稳健性)
【讨论】:
启用FipsAlgorithmPolicy
时这是一个不错的选择。【参考方案6】:
网上有很多使用ComputeHash()的例子。我的测试表明,通过网络连接运行时速度非常慢。下面的 sn-p 对我来说运行得更快,但是您的里程可能会有所不同:
$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
【讨论】:
您的方法克服了其他答案中 ReadAllBytes 的 2Gb 限制,这正是我所需要的。write-progress
行的反引号有什么作用?语法高亮似乎不喜欢它。
@mwfearnley 反引号使行继续。 blogs.technet.microsoft.com/heyscriptingguy/2015/06/19/…【参考方案7】:
PowerShell One-Liners(字符串到哈希)
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("-","")
【讨论】:
【参考方案8】:现在有一个 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
。
The example is from the official documentation of PowerShell 5.1。该文档有更多示例。
【讨论】:
如何仅使用 Get-FileHash 中的哈希值?【参考方案9】:正如接受的答案中所述,Get-FileHash
易于与文件一起使用,但也可以与字符串一起使用:
$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))
【讨论】:
【参考方案10】:这个网站有一个例子:Using Powershell for MD5 Checksums。它使用 .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()
【讨论】:
很好,但它不适用于只读文件!它需要 $stream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) 如果链接失效,答案将毫无用处。 ***.com/help/how-to-answer 为了回应我认为您的反对意见,我在此处剪切并粘贴了文章中的代码。去年我没有这样做,因为我觉得这是抄袭。添加斯蒂芬的只读改编让我觉得值得发布。 @neontapir 只是说:如果您不承认来源,逐字发布(或改编)只是抄袭。版权(法律上或道德上)是一个单独的问题,但对于大多数代码 sn-ps,我不会担心这一点。【参考方案11】:如果您从 Microsoft 下载 File Checksum Integrity Verifier (FCIV),这将成为单行代码。
我从这里下载了 FCIV: Availability and description of the File Checksum Integrity Verifier utility
运行以下命令。我有十个文件要检查。
Get-ChildItem WTAM*.tar | % .\fciv $_.Name
【讨论】:
【参考方案12】:右键菜单选项示例:
[HKEY_CLASSES_ROOT\*\shell\SHA1 PS check\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Get-FileHash -Algorithm SHA1 '%1'"
【讨论】:
【参考方案13】:这是我用来获取给定字符串的 MD5 的 sn-p:
$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"))
【讨论】:
【参考方案14】:这将返回远程计算机上文件的 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()
【讨论】:
【参考方案15】:团队! 看看我的哈希计算函数。
Function Get-StringHash
<#
.DESCRIPTION
Get string persistant hash.
#>
[OutputType([string])]
[CmdletBinding()]
Param(
[Parameter( Mandatory = $True, Position = 0, HelpMessage = "String to calculate hash." )]
[string] $String,
[Parameter( Mandatory = $false, Position = 0, HelpMessage = "String encoding." )]
[ValidateSet( 'UTF8' )]
[string] $StringEncoding = 'UTF8',
[Parameter( Mandatory = $false, Position = 2, HelpMessage = "Hash algoritm." )]
[ValidateSet( 'md5', 'sha256', 'sha512' )]
[string] $Algoritm = 'sha256'
)
try
#region functions
#endregion
$Result = $null
switch ( $Algoritm )
'md5'
$HashProvider = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
'sha256'
$HashProvider = New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider
'sha512'
$HashProvider = New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider
Default
switch ( $StringEncoding )
'UTF8'
$Encoding = New-Object -TypeName System.Text.UTF8Encoding
Default
$Result = [System.BitConverter]::ToString( $HashProvider.ComputeHash( $Encoding.GetBytes( $String ) )).replace('-','')
catch
Get-ErrorReporting -Trap $_
return $Result
$String = 'Some text'
$Algoritm = 'MD5'
$Hash = Get-StringHash -String $String -Algoritm $Algoritm
write-host "$String has $Algoritm hash $hash"
【讨论】:
很棒的工作@Alex,你真的在推进我们的团队!【参考方案16】:这是一个尝试验证 SHA256 指纹的漂亮打印示例。我使用 PowerShell v4 下载了 gpg4win v3.0.3(需要 Get-FileHash
)。
从https://www.gpg4win.org/download.html下载包,打开PowerShell,从下载页面获取hash,然后运行:
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
【讨论】:
【参考方案17】:这是一个单行命令示例,它计算 文件 的正确校验和,就像您刚刚下载的一样,并将其与发布的原始校验和进行比较。
例如,我为downloadings from the Apache JMeter project 编写了一个示例。在这种情况下,您有:
-
下载的二进制文件
在 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
第二个操作数是发布的校验和值。我们首先获取file.md5的内容,这是一个字符串,然后我们根据字符串格式提取哈希值:
Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash"
file 和 file.md5 必须在同一个文件夹中才能执行此命令。
【讨论】:
【参考方案18】:这是我用来获得一致哈希值的方法:
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/?【参考方案19】:(
[System.Security.Cryptography.MD5CryptoServiceProvider]::new().ComputeHash(
[System.Text.UTF8Encoding]::new().GetBytes($yourText)
) `
| % [Convert]::ToString($_, 16)
) -join ''
$yourText = 'hello'
产生5d41402abc4b2a76b9719d911017c592
【讨论】:
以上是关于如何在 PowerShell 中获取 MD5 校验和的主要内容,如果未能解决你的问题,请参考以下文章
用PowerShell的命令行检查文件的校验MD5 SHA1 SHA256
利用Windows系统自带的Powershell功能计算文件的MD5SHA256等Hash值