PowerShell 的 Get-FileHash 命令查询一个文件的所有上述哈希值(假设是 SHA256, MD5, SHA1, SHA384, 和 SHA512),你需要分别对每个算法运行该命令

Get‑FileHash 拆解 解构 底层原理 依赖文件 依赖关系 逻辑链路 配套链

定位Get‑FileHash 是 PowerShell 内置 Cmdlet,用于计算文件哈希(MD5、SHA1、SHA256、SHA384、SHA512);
 
PowerShell 5.1 / PowerShell 7+ 均原生自带,不需要额外安装模块
整体层级总览
plaintext
PowerShell: Get‑FileHash [-Path] <string> [-Algorithm]
        ↓
Microsoft.PowerShell.Utility.dll (Cmdlet托管实现)
        ↓
.NET System.Security.Cryptography 哈希抽象类
        ↓
Windows CNG(Cryptography Next Generation) / CryptoAPI
        ↓
Win32文件API ReadFile 读取文件字节流
        ↓
文件磁盘数据送入哈希算法 → 输出哈希摘要 → 封装为FileHash对象输出

一、底层原理

1、Cmdlet 本体

Get‑FileHash 属于 Microsoft.PowerShell.Utility 模块,编译在 Microsoft.PowerShell.Utility.dll
 
核心功能:打开目标文件,分块读取文件字节流,送入.NET 密码学哈希类,计算摘要,返回结构化 FileHash 对象。
支持算法:
  • SHA256默认算法)、SHA1、SHA384、SHA512、MD5
MD5/SHA1 仅兼容用途,不建议安全校验场景使用。

2、.NET 密码学层

内部调用 System.Security.Cryptography.HashAlgorithm 抽象工厂:
csharp
 
运行
HashAlgorithm.Create(algorithmName);
  • Windows 平台:底层调用 CNG(下一代密码学)bcrypt.dll,硬件支持时可使用 CPU 指令加速哈希计算;
  • 不是 PowerShell 自己实现哈希算法,只是做文件 IO + 调用系统密码学库。

3、文件读取逻辑(重点)

  1. 以只读模式打开文件流 FileStream
  2. 分块缓冲区读取(默认缓冲区大小),不会一次性把整个文件全部加载进内存
大文件(几十 GB)也可以正常计算哈希,不会爆内存;逐块送入哈希更新 TransformBlock()
  1. 全部流读完,调用 TransformFinalBlock() 获取最终哈希字节摘要。
  2. 将字节摘要转为十六进制大写字符串。
  3. 封装为 FileHash PSObject 输出,包含:PathAlgorithmHash 属性。
⚠️重要特性:
 
Get‑FileHash 计算的是文件内容哈希;文件名称、修改时间、元数据不参与哈希计算;只有文件字节内容改变,Hash 才变化。

4、路径支持

支持本地文件、UNC 网络路径;不直接支持内存字符串;只对磁盘文件,不能直接对字符串做哈希
字符串哈希需要手动实例化.NET HashAlgorithm。

二、依赖文件清单

文件 作用
Microsoft.PowerShell.Utility.dll Get‑FileHash Cmdlet 托管实现
System.Security.Cryptography.dll .NET 哈希算法抽象层
bcrypt.dll Windows CNG 密码学原生库,实际哈希运算
kernel32.dll Win32 文件 API:CreateFile、ReadFile,读取磁盘文件
运行环境:
  • PowerShell5.1:依赖 .NET Framework;
  • PowerShell7+:依赖 .NET Core;跨平台 Windows/Linux/macOS 均可用。

三、依赖关系梳理

  1. 权限依赖
     
    需要目标文件读取权限;没有读权限直接抛出文件访问异常。不需要管理员权限,普通用户可读文件即可计算哈希。
  2. 文件系统依赖
  • 文件被其他程序独占锁定:Get‑FileHash 打开失败,报文件正在使用;
  • 网络 UNC 路径:依赖 SMB 连通性,受网络抖动影响。
  1. 算法可用性依赖
     
    MD5、SHA1、SHA2 系列依赖系统 CNG 密码提供程序;极简 / 安全加固裁剪系统下极少数密码算法被策略禁用,会抛出算法不支持。
  2. 内存模型优势
     
    分块流式计算,文件大小不占用对等内存;无论几 GB 文件,缓冲区固定大小。
  3. 输出对象依赖
     
    输出是 FileHash 对象;如果直接输出到文本,PowerShell 会做格式化;导出原始哈希值建议访问 .Hash 属性。

四、完整逻辑链路

链路:Get‑FileHash C:\test.iso -Algorithm SHA256

  1. PowerShell 解析命令,定位内置 Cmdlet Get‑FileHash
  2. 参数绑定:Path 赋值文件路径,Algorithm 选择 SHA256;
  3. Cmdlet 内部调用.NET FileStream 只读打开目标文件;
  4. 根据 Algorithm 名称,工厂创建对应的 HashAlgorithm 实例(底层绑定 bcrypt CNG);
  5. 循环分块读取磁盘文件字节流;每一块调用 HashAlgorithm.TransformBlock() 更新哈希状态;
  6. 文件读取完毕,执行 TransformFinalBlock(),得到最终哈希字节数组;
  7. 将字节数组转为大写十六进制字符串;
  8. 构造 FileHash 对象,填充 PathAlgorithmHash;输出到 PowerShell 管道。
  9. 自动释放 FileStream 与 HashAlgorithm 资源。
关键:哈希计算是流式迭代更新,不是全部读完再计算。

五、配套链:实操示例

powershell
# 默认SHA256
Get‑FileHash C:\test.iso

# 指定MD5
Get‑FileHash C:\test.iso ‑Algorithm MD5

# 只输出哈希字符串
(Get‑FileHash C:\test.iso).Hash

# 批量计算目录下全部文件哈希
Get‑ChildItem C:\test\* ‑File | Get‑FileHash

# 输出到CSV
Get‑ChildItem C:\test\* ‑File | Get‑FileHash | Export‑Csv hashlist.csv ‑NoTypeInformation
补充:如果需要对字符串计算哈希(Get‑FileHash 做不到),直接调用.NET 哈希类:
powershell
$enc = [System.Text.Encoding]::UTF8
$bytes = $enc.GetBytes("teststring")
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$hashBytes = $sha256.ComputeHash($bytes)
[BitConverter]::ToString($hashBytes).Replace("-","")

六、故障排查清单

  1. Get‑FileHash : 无法访问文件
文件不存在 / 路径错误 / 当前用户没有文件读权限 / 文件被独占锁定。
  1. 算法名称无效
只支持:SHA256、SHA1、SHA384、SHA512、MD5;拼写错误会报错。
  1. 大文件执行慢,但内存占用很低
属于正常现象:磁盘 IO 瓶颈,流式计算不会吃内存。
  1. 同一个文件,两台机器哈希不一样
确认文件字节是否完全一致;元数据、时间戳不影响哈希;只要 Hash 不同,文件字节一定存在差异。
  1. UNC 网络文件哈希计算慢
全部文件字节需要通过网络 SMB 读取,受带宽影响。

七、关键认知误区澄清

❌误区 1:Get‑FileHash 会把整个文件加载进内存
 
✅事实:分块流式读取,大文件不会占用大量内存。
❌误区 2:哈希包含文件属性、修改时间
 
✅事实:只计算文件原始字节内容;文件名、时间、ACL 元数据不参与。
❌误区 3:Get‑FileHash 可以直接计算字符串哈希
 
✅事实:只能处理磁盘文件;字符串需要手动调用.NET 密码学类。
❌误区 4:PowerShell 自己实现 SHA256 算法
 
✅事实:Cmdlet 只是封装 IO 和对象输出;真正哈希运算由 Windows CNG bcrypt.dll 完成。
❌误区 5:MD5 适合安全校验
 
✅事实:MD5、SHA1 存在碰撞风险,仅用于快速比对,安全校验优先 SHA256。
 

PowerShell 是一种跨平台的任务自动化解决方案,包含一个命令行外壳、脚本语言和配置管理框架。PowerShell 提供了用于计算文件哈希值的内置命令 Get-FileHashGet-FileHash 命令可以用来计算文件的哈希值,支持多种哈希算法。 ,Get-FileHash 支持以下几种哈希算法:

  1. SHA256:默认算法,提供了较好的安全性。
  2. MD5:较早的算法,现在不推荐使用,因为其安全性较低。
  3. SHA1:比MD5新,但是现在也被认为是不够安全的。
  4. SHA384:比SHA256更长的哈希值,提供更高的安全性。
  5. SHA512:比SHA384还要长的哈希值,提供最高的安全性。

 

如果在将 Get-FileHash 的输出重定向到文本文件时遇到哈希值显示不完整的问题,这通常是因为输出格式化的原因。为了确保哈希值在输出文件中完整显示,最好直接提取哈希值属性进行输出。以下是如何做到这一点的步骤:

1. 直接输出哈希值到文件

你可以只提取哈希值本身(通过访问 .Hash 属性),然后将这个值输出到文件,这样可以确保哈希值不会被截断。

powershellCopy Code
(Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512).Hash | Out-File -FilePath C:\output.txt

这条命令首先计算指定文件的 SHA512 哈希值,然后直接从结果对象中提取 Hash 属性的值(即哈希值字符串),最后将这个字符串写入 C:\output.txt 文件中。

2. 使用自定义格式化输出到文件

如果你还想在输出文件中包含算法名称和路径等信息,但又希望哈希值完整无缩略,可以使用自定义的 PowerShell 脚本片段来格式化输出内容。

powershellCopy Code
$fileHash = Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512
$outputString = "Algorithm: $($fileHash.Algorithm)`r`nHash: $($fileHash.Hash)`r`nPath: $($fileHash.Path)"
$outputString | Out-File -FilePath C:\output.txt

这段脚本首先计算文件的哈希值,并将结果存储在 $fileHash 变量中。然后,它构造一个包含算法、哈希值和路径的字符串($outputString),其中哈希值是完整的,没有被截断。最后,这个字符串被写入到指定的文件中。

这样,无论哈希值有多长,都可以确保在输出文件中完整地展示出来,同时还能包含一些额外的有用信息。

 

在 PowerShell 中,当你使用 Get-FileHash 命令获取文件的哈希值时,如果哈希值很长(如 SHA512),输出可能会被截断以适应控制台窗口的宽度。为了显示完整的哈希值,你可以尝试以下几种方法:

1. 增加控制台窗口的宽度

这是最简单的解决方案之一,尽管它可能不总是可行或方便。你可以尝试手动调整 PowerShell 窗口的宽度,使其足够宽,以便能够显示完整的哈希值。

2. 使用 Format-Table 命令的 -Wrap 参数

Format-Table 是 PowerShell 中用于格式化输出的一个命令,它有一个 -Wrap 参数,可以用来包装长文本,以便在下一行继续显示,而不是截断它。

powershellCopy Code
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Format-Table -AutoSize -Wrap

3. 使用 Format-Table 命令的 -AutoSize 参数

虽然 -AutoSize 参数主要用于自动调整列的宽度以适应内容,但它有时也可以帮助更好地显示长文本。

powershellCopy Code
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Format-Table -AutoSize

4. 直接输出哈希值属性

如果你只对哈希值本身感兴趣,可以直接选择 .Hash 属性,这样就会输出完整的哈希值,而不包含其他信息。

powershellCopy Code
(Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512).Hash

5. 输出到文件

另一个选项是将输出重定向到一个文本文件中,这样你就可以用文本编辑器打开它并查看完整的哈希值。

powershellCopy Code
Get-FileHash -Path "C:\Users\Administrator\Desktop\下载 (1).png" -Algorithm SHA512 | Out-File -FilePath C:\path\to\output.txt

请将 C:\path\to\output.txt 替换为你想要保存输出文件的实际路径。然后,你可以使用任何文本编辑器打开这个文件来查看完整的哈希值。

以上方法中的任何一个都可以帮助你查看到完整的哈希值,具体使用哪一个取决于你的个人偏好和具体情况。

 

你可以通过指定 -Algorithm 参数来选择这些算法中的任何一个。例如,如果你想为某个文件计算SHA512哈希值,可以使用如下命令:

powershellCopy Code
Get-FileHash -Path "C:\path\to\your\file.txt" -Algorithm SHA512

这会返回该文件的SHA512哈希值。

请注意,随着时间的推移,可能会有更多的哈希算法被添加到PowerShell中,或者一些算法可能因安全考虑而不再推荐使用。因此,建议查看最新的PowerShell文档或使用 Get-Help Get-FileHash 命令来获取最新信息。

 

要使用 PowerShell 的 Get-FileHash 命令查询一个文件的所有上述哈希值(假设是 SHA256, MD5, SHA1, SHA384, 和 SHA512),你需要分别对每个算法运行该命令。PowerShell 不提供直接查询所有哈希值的单一命令,但你可以通过编写一个简短的脚本来实现这一功能。

以下是一个示例脚本,它将为指定路径的文件计算所有提及的哈希值:

powershellCopy Code
# 指定文件路径
$filePath = "C:\path\to\your\file.txt"

# 定义支持的哈希算法列表
$hashAlgorithms = @("SHA256", "MD5", "SHA1", "SHA384", "SHA512")

# 遍历算法列表,为每种算法计算哈希值
foreach ($algorithm in $hashAlgorithms) {
    $hash = Get-FileHash -Path $filePath -Algorithm $algorithm
    Write-Output "$algorithm hash of `"$filePath`": $($hash.Hash)"
}

将上面的脚本保存到一个 .ps1 文件中或直接在 PowerShell 控制台中运行它。确保替换 $filePath 变量的值为你想要计算哈希值的文件的实际路径。这个脚本会遍历所有指定的哈希算法,为每一个算法输出对应的哈希值。

 

PowerShell 的 Get-FileHash 命令主要支持的哈希算法包括了你提到的 SHA256, MD5, SHA1, SHA384, 和 SHA512。这些算法是最常用且广泛支持的。

除了这些常见的算法,根据不同版本的 PowerShell 和 Windows 环境,可能还有其他哈希算法可用,但它们并不是 Get-FileHash 命令的标准选项。Get-FileHash 命令的设计初衷是提供一种简单方式来计算文件的哈希值,因此它只包含了一些最广泛使用的算法。

如果需要计算其他类型的哈希值,你可能需要依赖其他工具或自定义脚本来实现。例如,可以使用 .NET 类库中的加密功能来计算其他类型的哈希值。下面是一个使用 .NET 类库计算 RIPEMD-160 哈希值的示例:

powershellCopy Code
# 加载目标类
$ripemd160 = [System.Security.Cryptography.RIPEMD160Managed]::new()

# 计算哈希值
function Get-RipeMD160Hash($filePath) {
    $fileStream = [System.IO.File]::OpenRead($filePath)
    $hashValue = $ripemd160.ComputeHash($fileStream)
    $fileStream.Close()
    return [BitConverter]::ToString($hashValue) -replace '-', ''
}

# 使用函数
$filePath = "C:\path\to\your\file.txt"
$hash = Get-RipeMD160Hash $filePath
Write-Output "RIPEMD-160 hash of `"$filePath`": $hash"

请注意,RIPEMD-160 只是作为示例,而且在某些环境中可能不直接支持。此外,对于特定的哈希算法,你可能需要安装额外的软件或库。

 

在密码学和信息安全领域,除了上文提及的 SHA256, MD5, SHA1, SHA384, 和 SHA512 等哈希算法外,还存在许多其他的哈希函数。它们各自有不同的设计目的、安全性水平和应用场景。以下是一些其他的哈希算法,虽然这些可能不直接通过 PowerShell 的 Get-FileHash 命令支持,但它们在某些特定的应用中很重要:

  1. RIPEMD-160: 一种较旧的哈希函数,设计用于替代 MD4、MD5 和 RIPEMD。RIPEMD-160 输出为160位。

 

posted @ 2024-02-07 08:43  suv789  阅读(1962)  评论(0)    收藏  举报