2

We have script written in powershell to get some information from users terminal. And have created SHA1 of that information, just to verify integrity of result.

On server side where we get these information from multiple terminals, we are verifying each results and this side of script is being written in Ruby.

Now problem, is that both these script are giving different SHA1 hash, and I am not sure where I am making mistake.

Powershell code is as given below.

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

and this the hash we get for above script e7c527068445c52635287b9ecf55566c2564d595

below is Ruby script

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)

and here is the SHA1 has we get from this script. 77f7cecb2b75c16b1e929a56b644fad7d7f95965

Now condition here is, I can't make/propose any changes in Powershell part. I need to tune ruby code to make it match.

  • 4
    I am not an expert with encodings so this may be incorrect, this issue might be that in the Ruby example you are encoding the string in ISO_8859_1 while in the PowerShell example you are encoding the string in UTF8. This could lead to the difference observed but I am not confident enough to be sure! Please see this link https://stackoverflow.com/questions/7048745/what-is-the-difference-between-utf-8-and-iso-8859-1 – Persistent13 Jan 16 '19 at 18:59
  • Could also be the linefeeds. Windows has `\r\n` and linux has `\n`. This, I believe, is not affected by the encoding. – Kimmo Lehto Jan 17 '19 at 07:33
  • Both scripts are running on windows platform. – Jigish Thakar Jan 17 '19 at 11:27

2 Answers2

4

The encoding makes no difference in this situation, as we're only dealing with ASCII characters, and they both encode ASCII the same way. The problem is

  1. Your data is different in both cases, note the spaces preceding Directory and ControlCase in your first example but not present in the second.

  2. You need to escape the backslashes in the ruby string, or it interprets them as escape characters

Once you resolve these two issues, you will get the same result:

PS:

PS H:\> $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
>>
>> "
PS H:\> Get-Hash($string)
6454c0ecf1700448fb2496037a1e9ce496b185cd

Ruby:

>> 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 
..  
.. "
>> puts Digest::SHA1.hexdigest(varj.encode(Encoding::UTF_8))
=> 6454c0ecf1700448fb2496037a1e9ce496b185cd
>> puts Digest::SHA1.hexdigest(varj.encode(Encoding::ISO_8859_1))
=> 6454c0ecf1700448fb2496037a1e9ce496b185cd

Edit:

If you're still not able to match, I think the best approach is to compare the byte values of each string to identify differences.

PS:

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

Ruby:

>> varj_Encoded.bytes.to_a
=> [10, 10, 32, 32, ...
cody
  • 11,045
  • 3
  • 21
  • 36
  • 1
    Good call @cody ! It's worth mentioning that although encoding wasn't an issue with _this specific data_, it would be an issue with other data where UTF-8 and ISO-8859-1 encodings differ. – briantist Jan 16 '19 at 19:52
  • Thanks @cody, I tried with bypassing back slash - result is still different. and space at the start of line was a mistake while posting questions. in my code file both are same. I am not sure how you are getting hash same from both the scripts. – Jigish Thakar Jan 17 '19 at 11:28
  • @JigishThakar Hmm, I think your best bet is to compare the byte values of each string to figure out what is different. See my edit. – cody Jan 17 '19 at 11:40
  • Thanks @cody, let me try that. – Jigish Thakar Jan 17 '19 at 12:48
0

As Persistent13 mentioned in a comment, the encoding difference is the most likely reason. The encoding class in .Net has a few static members corresponding to common encodings but ISO-8859-1 isn't one of them. You can see the rest with [System.Text.Encoding]::GetEncodings() and you can get a specific one with [System.Text.Encoding]::GetEncoding() (there are a few overloads).

So for example, try this:

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

Since you can't change the PowerShell part, you can do this just to test the theory in the console.

Or go right to the part of changing Ruby to use UTF8.

varj_Encoded = varj.encode(Encoding::UTF-8)
puts Digest::SHA1.hexdigest(varj_Encoded)
briantist
  • 45,546
  • 6
  • 82
  • 127