1
votes

Goal: Upload a file to Azure Blob Storage and set MD5 that can be validated when a user downloads the file.

Using Azure CLI Powershell.

Get-FileHash -Algorithm MD5 .\AutoSetup.zip
Algorithm       Hash                                             Path
---------       ----                                             ----
MD5             693EF0DB938308AC2C362F50F7CB9F9F                 C:\MyFiles\AutoSetup.zip

az storage blob upload --account-name mystorageaccount --container-name mycontainername --file AutoSetup.zip --name Autosetup2.zip --content-md5 693EF0DB938308AC2C362F50F7CB9F9F
Finished[#############################################################]  100.0000%
The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded. ErrorCode: InvalidMd5
<?xml version="1.0" encoding="utf-8"?><Error><Code>InvalidMd5</Code><Message>The MD5 value specified in the request is invalid. MD5 value must be 128 bits and base64 encoded.
RequestId:9f27334a-801e-0028-6db4-3539c5000000
Time:2020-05-29T12:28:23.7677258Z</Message></Error>

Edit 1:

I've also attempted getting the hash this way

$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
69-3E-F0-DB-93-83-08-AC-2C-36-2F-50-F7-CB-9F-9F

It seems that no matter what I do, the MD5 that is returned for the file is 693EF0DB938308AC2C362F50F7CB9F9F but Azure won't take it...

Edit 2:

I've generated a random 128-bit string $B&E)H@McQfTjWnZ and proceeded to encode it in Base64 which gave me JEImRSlIQE1jUWZUalduWg== When I attempt to upload a blob with THAT hash, I get a different error message:

The MD5 value specified in the request did not match with the MD5 value calculated by the server. ErrorCode: Md5Mismatch

The above makes sense, cause I just created a random 128 bit base64 encoded hash. However, now I am wondering why the Powershell's Get-FileHash command gives me what seems to be incorrect?

What can be causing the error?

2

2 Answers

1
votes

Try converting the hash into a Base64 encoded string. Something like:

$someFilePath = "C:\MyFiles\AutoSetup.zip"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider    
$hash = [System.Convert]::ToBase64String($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
Write-Host $hash
8SzzdVQAV4Wdbp8Z9qsczg==
1
votes

I wanted to add my own "solution" to this, just in case someone prefers this approach.

Approach 1 is described in the answer by Gaurav. We read the bytes from the file, compute MD5, and encode it with Base64. This will result in MD5 string that az storage blob upload will validate and accept. This seems to be the correct way.

Approach 2 is to upload the file without setting content-md5 and update it after.

Get MD5 hash

Get-FileHash -Algorithm MD5 .\AutoSetup.zip
Algorithm       Hash                                             Path
---------       ----                                             ----
MD5             693EF0DB938308AC2C362F50F7CB9F9F                 C:\MyFiles\AutoSetup.zip

Upload the blob without MD5

az storage blob upload --account-name mystorageaccount --container-name mycontainername --file AutoSetup.zip --name Autosetup2.zip
Finished[#############################################################]  100.0000%

Update the blob with content-md5. We can write anything we want to it here, so using the MD5 from earlier is fine!

az storage blob update --account-name mystorageaccount --container-name mycontainername --name Autosetup2.zip -- content-md5 693EF0DB938308AC2C362F50F7CB9F9F

I don't know how correct the 2nd approach is, but it will work nonetheless.