Powershell 和 Ruby 中不同的 SHA1 哈希结果

Posted

技术标签:

【中文标题】Powershell 和 Ruby 中不同的 SHA1 哈希结果【英文标题】:Different SHA1 hash result in Powershell and Ruby 【发布时间】:2019-06-10 22:08:07 【问题描述】:

我们用 powershell 编写了脚本来从用户终端获取一些信息。并创建了该信息的 SHA1,只是为了验证结果的完整性。

在我们从多个终端获取这些信息的服务器端,我们正在验证每个结果,并且脚本的这一端是用 Ruby 编写的。

现在的问题是,这两个脚本都给出了不同的 SHA1 哈希值,我不确定我在哪里犯了错误。

Powershell 代码如下。

$String = "

    Directory: D:\OneDrive -
    ControlCase\jt-work\evidance-collection\evidances-text\PCI_Evidences_CCIN-CAS-VKAUS\evidences


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2019-01-16   1:14 PM       7073 21_to_calc_hash.ps1
-a---        2019-01-16   1:15 PM       9973 CCIN-CAS-VKAUS_pci_evidence_Q21.txt
-a---        2019-01-15   9:37 PM      67399 CCIN-CAS-VKAUS_pci_evidence_Q23.txt
-a---        2019-01-15   9:37 PM       5055 CCIN-CAS-VKAUS_pci_evidence_Q34.txt
-a---        2019-01-15   9:38 PM      10820 CCIN-CAS-VKAUS_pci_evidence_Q45.txt
-a---        2019-01-15   9:38 PM      13129 CCIN-CAS-VKAUS_pci_evidence_Q50.txt
-a---        2019-01-15   9:38 PM       7163 CCIN-CAS-VKAUS_pci_evidence_Q67.txt
-a---        2019-01-15   9:39 PM       4301 CCIN-CAS-VKAUS_pci_evidence_Q69.txt
-a---        2019-01-15   9:39 PM       2900 CCIN-CAS-VKAUS_pci_evidence_Q81.txt

"

Function Get-Hash([String] $String)
 
$StringBuilder = New-Object System.Text.StringBuilder 
[System.Security.Cryptography.HashAlgorithm]::Create("sha1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|% 
[Void]$StringBuilder.Append($_.ToString("x2")) 
 
$StringBuilder.ToString() 


Get-Hash($String)

这是我们为上述脚本得到的哈希e7c527068445c52635287b9ecf55566c2564d595

下面是 Ruby 脚本

require 'digest'
varj = "

Directory: D:\OneDrive -
ControlCase\jt-work\evidance-collection\evidances-text\PCI_Evidences_CCIN-CAS-VKAUS\evidences


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2019-01-16   1:14 PM       7073 21_to_calc_hash.ps1
-a---        2019-01-16   1:15 PM       9973 CCIN-CAS-VKAUS_pci_evidence_Q21.txt
-a---        2019-01-15   9:37 PM      67399 CCIN-CAS-VKAUS_pci_evidence_Q23.txt
-a---        2019-01-15   9:37 PM       5055 CCIN-CAS-VKAUS_pci_evidence_Q34.txt
-a---        2019-01-15   9:38 PM      10820 CCIN-CAS-VKAUS_pci_evidence_Q45.txt
-a---        2019-01-15   9:38 PM      13129 CCIN-CAS-VKAUS_pci_evidence_Q50.txt
-a---        2019-01-15   9:38 PM       7163 CCIN-CAS-VKAUS_pci_evidence_Q67.txt
-a---        2019-01-15   9:39 PM       4301 CCIN-CAS-VKAUS_pci_evidence_Q69.txt
-a---        2019-01-15   9:39 PM       2900 CCIN-CAS-VKAUS_pci_evidence_Q81.txt

"

varj_Encoded = varj.encode(Encoding::ISO_8859_1)
puts Digest::SHA1.hexdigest(varj_Encoded)

这是我们从这个脚本中得到的 SHA1。 77f7cecb2b75c16b1e929a56b644fad7d7f95965

现在的条件是,我不能对 Powershell 部分进行/提出任何更改。我需要调整 ruby​​ 代码以使其匹配。

【问题讨论】:

我不是编码专家,所以这可能是不正确的,这个问题可能是在 Ruby 示例中您使用 ISO_8859_1 对字符串进行编码,而在 PowerShell 示例中您使用 UTF8 对字符串进行编码。这可能会导致观察到的差异,但我没有足够的信心来确定!请看这个链接***.com/questions/7048745/… 也可以是换行符。 Windows 有\r\n,Linux 有\n。我相信这不受编码的影响。 两个脚本都在windows平台上运行。 【参考方案1】:

在这种情况下,编码没有区别,因为我们只处理 ASCII 字符,它们都以相同的方式编码 ASCII。问题是

    您的数据在两种情况下都不同,请注意第一个示例中 DirectoryControlCase 前面的空格,但在第二个示例中不存在。

    您需要对 ruby​​ 字符串中的反斜杠进行转义,或者将其解释为转义字符

一旦你解决了这两个问题,你会得到同样的结果:

PS:

PS H:\> $String = " >> >> 目录:D:\OneDrive - >> ControlCase\jt-work\evidance-collection\evidances-text\PCI_Evidences_CCIN-CAS-VKAUS\evidences >> >> >> 模式 LastWriteTime 长度名称 >> ---- ------------- ------ ---- >> -a--- 2019-01-16 1:14 PM 7073 21_to_calc_hash.ps1 >> -a--- 2019-01-16 1:15 PM 9973 CCIN-CAS-VKAUS_pci_evidence_Q21.txt >> -a--- 2019-01-15 9:37 PM 67399 CCIN-CAS-VKAUS_pci_evidence_Q23.txt >> -a--- 2019-01-15 9:37 PM 5055 CCIN-CAS-VKAUS_pci_evidence_Q34.txt >> -a--- 2019-01-15 9:38 PM 10820 CCIN-CAS-VKAUS_pci_evidence_Q45.txt >> -a--- 2019-01-15 9:38 PM 13129 CCIN-CAS-VKAUS_pci_evidence_Q50.txt >> -a--- 2019-01-15 9:38 PM 7163 CCIN-CAS-VKAUS_pci_evidence_Q67.txt >> -a--- 2019-01-15 9:39 PM 4301 CCIN-CAS-VKAUS_pci_evidence_Q69.txt >> -a--- 2019-01-15 9:39 PM 2900 CCIN-CAS-VKAUS_pci_evidence_Q81.txt >> >> " PS H:\> Get-Hash($string) 6454c0ecf1700448fb2496037a1e9ce496b185cd

鲁比:

>> 变量 = " .. .. 目录:D:\\OneDrive - .. ControlCase\\jt-work\\evidance-collection\\evidances-text\\PCI_Evidences_CCIN-CAS-VKAUS\\evidences .. .. .. 模式 LastWriteTime 长度 名称 .. ---- ------------- ------ ---- .. -a--- 2019-01-16 1:14 PM 7073 21_to_calc_hash.ps1 .. -a--- 2019-01-16 1:15 PM 9973 CCIN-CAS-VKAUS_pci_evidence_Q21.txt .. -a--- 2019-01-15 9:37 PM 67399 CCIN-CAS-VKAUS_pci_evidence_Q23.txt .. -a--- 2019-01-15 9:37 PM 5055 CCIN-CAS-VKAUS_pci_evidence_Q34.txt .. -a--- 2019-01-15 9:38 PM 10820 CCIN-CAS-VKAUS_pci_evidence_Q45.txt .. -a--- 2019-01-15 9:38 PM 13129 CCIN-CAS-VKAUS_pci_evidence_Q50.txt .. -a--- 2019-01-15 9:38 PM 7163 CCIN-CAS-VKAUS_pci_evidence_Q67.txt .. -a--- 2019-01-15 9:39 PM 4301 CCIN-CAS-VKAUS_pci_evidence_Q69.txt .. -a--- 2019-01-15 9:39 PM 2900 CCIN-CAS-VKAUS_pci_evidence_Q81.txt .. ……” >> 将 Digest::SHA1.hexdigest(varj.encode(Encoding::UTF_8)) => 6454c0ecf1700448fb2496037a1e9ce496b185cd >> 将 Digest::SHA1.hexdigest(varj.encode(Encoding::ISO_8859_1)) => 6454c0ecf1700448fb2496037a1e9ce496b185cd

编辑:

如果还是不能匹配,我认为最好的方法是比较每个字符串的字节值来识别差异。

PS:

PS H:\> $enc = [system.Text.Encoding]::UTF8 PS H:\> $enc.GetBytes($String) 10 10 32 32 ...

鲁比:

>> varj_Encoded.bytes.to_a => [10, 10, 32, 32, ...

【讨论】:

好电话@cody!值得一提的是,虽然 此特定数据 的编码不是问题,但 UTF-8 和 ISO-8859-1 编码不同的其他数据可能会出现问题。 感谢@cody,我尝试绕过反斜杠 - 结果仍然不同。在发布问题时,行首的空格是错误的。在我的代码文件中两者都是相同的。我不确定你是如何从两个脚本中获得相同的哈希值的。 @JigishThakar 嗯,我认为您最好的选择是比较每个字符串的字节值以找出不同之处。查看我的编辑。 谢谢@cody,让我试试看。【参考方案2】:

正如 Persistent13 在评论中提到的,编码差异是最可能的原因。 .Net 中的编码类有一些与常见编码相对应的静态成员,但 ISO-8859-1 不是其中之一。你可以用[System.Text.Encoding]::GetEncodings() 看到其余的,你可以用[System.Text.Encoding]::GetEncoding() 得到一个特定的(有一些重载)。

例如,试试这个:

$bytes = [System.Text.Encoding]::GetEncoding('iso-8859-1').GetBytes($string)
[System.Security.Cryptography.HashAlgorithm]::Create("sha1").ComputeHash($bytes)

由于您无法更改 PowerShell 部分,您可以这样做只是为了在控制台中测试理论。

或者直接进入将 Ruby 更改为使用 UTF8 的部分。

varj_Encoded = varj.encode(Encoding::UTF-8)
puts Digest::SHA1.hexdigest(varj_Encoded)

【讨论】:

以上是关于Powershell 和 Ruby 中不同的 SHA1 哈希结果的主要内容,如果未能解决你的问题,请参考以下文章

sh 使用RVM创建.ruby-version和.ruby-gemset文件

sh 在Ubuntu 14.04上使用rbenv和ruby-build安装ruby 2.2.3

php EOF(heredoc)使用

sh ruby-cygwin.sh

sh cara pemasangan windows powershell di linux debian衍生物

sh 关于Ruby环境的注释