Issue
Using Powershell script we always match the HASH value of a file on the WEB URI and the hash after it's downloaded and report failure if the hash does not match.
I'm now dealing with the below URL where Im unable to match the HASH MD5 on URI totmYatp14JwNhBLZwYpog==
to MD5 on local B68B6661AB69D7827036104B670629A2
?.
https://cdn.windwardstudios.com/Archive/23.X/23.3.5/JavaRESTfulEngine-23.3.5.1.zip
There is Content-MD5
mentioned totmYatp14JwNhBLZwYpog==
on the below URL for the file:
https://cdn.windwardstudios.com/?prefix=Archive/23.X/23.3.5/
Is it possible to match Hash
or any other solution to make sure that the file on the webpage and the one after the download match?
Below is what I tried but the MD5 does not match:
MD5 and content-length for the concerned file from headers are below:
PS C:\Users\HOME> $response = Invoke-WebRequest -Uri "https://cdn.windwardstudios.com/Archive/23.X/23.3.5/JavaRESTfulEngine-23.3.5.1.zip" -Method Head
PS C:\Users\HOME> $response.Headers['Content-MD5']
totmYatp14JwNhBLZwYpog==
PS C:\Users\HOME> $response.Headers['Content-Length']
189583636
However, when the same file is downloaded locally its content-length
MATCHES but the content-md5
DOES NOT MATCH when it should:
$filePath = 'C:\Users\HOME\Downloads\JavaRESTfulEngine-23.3.5.1.zip'
# Calculate the MD5 hash of the file
$md5 = Get-FileHash -Path $filePath -Algorithm MD5
Write-Host ("MD5 hash (Content-MD5) of " + $filePath + ": " + $md5.Hash)
$fileInfo = Get-Item $filePath
$fileInfo.Length
As you can see from the output the content-length
matches but the content-MD5
does not.
PS C:\Users\HOME> C:\Logs\getkey.ps1
MD5 hash (Content-MD5) of C:\Users\HOME\Downloads\JavaRESTfulEngine-23.3.5.1.zip: B68B6661AB69D7827036104B670629A2
189583636
How can I get the MD5 on URI totmYatp14JwNhBLZwYpog==
to match MD5 on local B68B6661AB69D7827036104B670629A2
?
**** Trying solution by @vonPryz ****
# Convert MD5 hash to Base64
$md5Base64 = [Convert]::ToBase64String($md5.Hash)
Write-Host "MD5 in Base64: $md5Base64"
# Convert Base64 MD5 hash to Hex
$md5Bytes = [Convert]::FromBase64String($md5Base64)
$md5Hex = [System.BitConverter]::ToString($md5Bytes) -replace '[-\s]', ''
Write-Host "MD5 in Hex: $md5Hex"
Output:
Cannot convert argument "inArray", with value: "B68B6661AB69D7827036104B670629A2", for "ToBase64String" to type "System.Byte[]": "Cannot convert value
"B68B6661AB69D7827036104B670629A2" to type "System.Byte[]". Error: "Cannot convert value "B68B6661AB69D7827036104B670629A2" to type "System.Byte". Error: "Input string
was not in a correct format."""
At C:\Logs\getkey.ps1:31 char:1
+ $md5Base64 = [Convert]::ToBase64String($md5.Hash)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Solution
The reason is the hash is represented in Base64 encoded format, whilst hashes are usually represented in hex strings.
Convert the format from Base64 and then to hex format. Like so,
([System.Convert]::FromBase64String($base64data) | Format-Hex).HexBytes -replace ' ',''
The .HexBytes
property contains bytes separated by spaces, so -replace ' ', ''
will trim the withespaces and you'll get an uppercase string containing the hash.
Answered By - vonPryz Answer Checked By - Dawn Plyler (WPSolving Volunteer)