如何在PowerShell中获取MD5校验和

如何在PowerShell中获取MD5校验和,powershell,powershell-2.0,Powershell,Powershell 2.0,我想计算一些内容的校验和。如何在PowerShell中执行此操作?此站点有一个示例:。它使用.NET framework实例化MD5哈希算法的一个实例来计算哈希 以下是文章中的代码,包括Stephen的评论: param ( $file ) $algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5") $stream = New-Object System.IO.FileStream($Path, [System.I

我想计算一些内容的校验和。如何在PowerShell中执行此操作?

此站点有一个示例:。它使用.NET framework实例化MD5哈希算法的一个实例来计算哈希

以下是文章中的代码,包括Stephen的评论:

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()

如果内容是字符串:

$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开始,使用cmdlet可以很容易地对开箱即用的文件执行此操作:

Get FileHash-算法MD5

这当然更可取,因为它避免了第一个解决方案在注释中指出的问题(使用流、关闭流并支持大文件)。

以下是两行,只需更改第2行中的“hello”:

如果您使用的是Get Hash命令,则可以轻松地执行此操作:

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


Algorithm: MD5


Path       :
HashString : E42B054623B3799CB71F0883900F2764

网上有很多使用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

下面是我用来处理相对路径和绝对路径的函数:

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块。

这将为远程计算机上的文件返回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()
}

如果从Microsoft下载文件校验和完整性验证器(FCIV),这将成为一行代码

我从这里下载了FCIV:

运行以下命令。我有十份文件要查

Get-ChildItem WTAM*.tar | % {.\fciv $_.Name}

右键单击菜单选项的示例:

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

现在有一个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即可


。文档中有更多示例。

这里是一个尝试验证SHA256指纹的漂亮打印示例。我使用PowerShell v4下载了gpg4win v3.0.3(需要
Get FileHash

从下载包,打开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)) 
}
输出:

True
文件gpg4win-3.0.3.exe的哈希匹配
另一个在Windows中默认安装的内置命令可以追溯到2003年,它当然也可以从PowerShell调用

CertUtil -hashfile file.foo MD5

(注意:MD5应该全部大写,以获得最大的健壮性)

这里是一个单行命令示例,它计算文件的正确校验和,就像您刚才下载的一样,并将其与原始文件的已发布校验和进行比较

例如,我写了一个例子。在这种情况下,您有:

  • 下载的二进制文件
  • 以一个字符串的形式发布在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必须位于同一文件夹中才能执行此命令。

    如接受答案中所述,易于与文件一起使用,但也可以与字符串一起使用:

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

    这就是我用来获得一致哈希值的方法:

    函数新CrcTable{
    [uint32]$c=$null
    $crcTable=新对象“System.Uint32[]”256
    对于($n=0;$n-lt 256;$n++){
    $c=[uint32]$n
    对于($k=0;$k-lt 8;$k++){
    如果($c-波段1){
    $c=(0xEDB88320-bxor($c-shr 1))
    }
    否则{
    $c=($c-shr 1)
    }
    }
    $crcTable[$n]=$c
    }
    写入输出$crcTable
    }
    函数更新Crc([uint32]$Crc,[byte[]]$buffer,[int]$length,$crcTable){
    [uint32]$c=$crc
    对于($n=0;$n-lt$length;$n++){
    $c=($c-bxor$buffer[$n])-band 0xFF])-bxor($c-shr 8)
    }
    写入输出$c
    }
    函数Get-CRC32{
    [CmdletBinding()]
    param(
    #用于CRC计算的字节数组
    [参数(位置=0,ValueFromPipeline=$true)]
    [ValidateNotNullOrEmpty()]
    [字节[]]$InputObject
    )
    $dataArray=@()
    $crcTable=新的crcTable
    foreach($InputObject中的项){
    $dataArray+=$item
    }
    $inputLength=$dataArray.Length
    写入输出((更新Crc-Crc 0xffffffffL-buffer$DATARRAY-length$INPUTLENGHT-crcTable$crcTable)-bxor 0xffffffffL)
    }
    函数GetHash(){
    [CmdletBinding()]
    param(
    [参数(位置=0,ValueFromPipeline=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$InputString
    )
    $bytes=[System.Text.Encoding]::UTF8.GetBytes($InputString)
    $hasCode=Get-CRC32$bytes
    $hex=“{0:x}”-f$hasCode
    返回$hex
    }
    函数Get FolderHash{
    [CmdletBinding()]
    param(
    [参数(位置=0,ValueFromPipeline=$true)]
    [ValidateNotNullOrEmpty()]
    [字符串]$FolderPath
    )
    $FolderContent=新对象System.Collections.ArrayList
    获取ChildItem$FolderPath-递归| Where对象{
    如果([System.IO.File]::存在($\ux)){
    $FolderContent.AddRange([System.IO.File]::ReadAllBytes($)| Out Null
    }
    }
    $hasCode=Get-CRC32$FolderContent
    $hex=“{0:x}”-f$hasCode
    返回$hex.Substring(0,8).ToLower()
    }
    
    以下是我用来获取给定字符串的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")}) 
    
    PowerShell一行程序(字符串到散列)

    MD5

    沙一

    SHA256

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

    ([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”参数调用“ReadAllBytes”时出现异常:“文件太长。此操作当前仅限于支持小于2 GB的文件(秒)。”
    
    ([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
    
    ([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")
    
    ([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")