Je voudrais calculer un MD5 somme de contrôle de certains contenus. Comment puis-je faire cela dans PowerShell?
Si le contenu est une chaîne:
$someString = "Hello World!"
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = new-object -TypeName System.Text.UTF8Encoding
$hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($someString)))
Si le contenu est un fichier:
$someFilePath = "C:\foo.txt"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))
À partir de PowerShell version 4, cette opération est facile à effectuer pour les fichiers prêts à l’emploi avec le Get-FileHash
cmdlet:
Get-FileHash <filepath> -Algorithm MD5
Cela est certainement préférable, car cela évite les problèmes que la première solution offre, comme indiqué dans les commentaires (utilise un flux, le ferme et prend en charge les fichiers volumineux).
Si vous utilisez les PowerShell Community Extensions , un commandlet Get-Hash vous permettra de le faire facilement:
C:\PS> "hello world" | Get-Hash -Algorithm MD5
Algorithm: MD5
Path :
HashString : E42B054623B3799CB71F0883900F2764
Voici les deux lignes, changez simplement "bonjour" à la ligne 2:
PS C:\> [Reflection.Assembly]::LoadWithPartialName("System.Web")
PS C:\> [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("hello", "MD5")
Voici une fonction que j'utilise qui gère les chemins relatifs et absolus:
function md5hash($path)
{
$fullPath = Resolve-Path $path
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$file = [System.IO.File]::Open($fullPath,[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
try {
[System.BitConverter]::ToString($md5.ComputeHash($file))
} finally {
$file.Dispose()
}
}
Merci à @davor ci-dessus pour la suggestion d'utiliser Open () au lieu de ReadAllBytes () et à @ jpmc26 pour la suggestion d'utiliser un bloc finally.
Il y a beaucoup d'exemples en ligne utilisant ComputeHash (). Mes tests ont montré que cela était très lent lors de l'exécution sur une connexion réseau. L'extrait ci-dessous est beaucoup plus rapide pour moi, cependant, YMMV:
$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
$fd = [System.IO.File]::OpenRead($file)
$buf = new-object byte[] (1024*1024*8) # 8mb buffer
while (($read_len = $fd.Read($buf,0,$buf.length)) -eq $buf.length){
$total += $buf.length
$md5.TransformBlock($buf,$offset,$buf.length,$buf,$offset)
write-progress -Activity "Hashing File" `
-Status $file -percentComplete ($total/$fd.length * 100)
}
# finalize the last read
$md5.TransformFinalBlock($buf,0,$read_len)
$hash = $md5.Hash
# convert hash bytes to hex formatted string
$hash | foreach { $hash_txt += $_.ToString("x2") }
write-Host $hash_txt
Ce site a un exemple: http://blog.brianhartsock.com/2008/12/13/using-powershell-for-md5-checksums/ . Il utilise le framework .NET pour instancier une instance de l'algorithme de hachage MD5 afin de calculer le hachage.
Voici le code de l'article, intégrant le commentaire de Stephen:
param
(
$file
)
$algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5")
$stream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read)
$md5StringBuilder = New-Object System.Text.StringBuilder
$algo.ComputeHash($stream) | % { [void] $md5StringBuilder.Append($_.ToString("x2")) }
$md5StringBuilder.ToString()
$stream.Dispose()
Une autre commande intégrée installée depuis longtemps par Windows depuis 2003 est certutil, qui peut bien sûr être appelée à partir de powershell.
CertUtil -hashfile file.foo MD5
(mise en garde: MD5 doit être en majuscule pour une robustesse maximale)
Cette question a presque 3 ans, depuis lors, comme certains l’ont commenté, il existe une fonction Get-FileHash qui est très pratique.
PS C:\> Get-FileHash C:\Users\Andris\Downloads\Contoso8_1_ENT.iso -Algorithm SHA384 | Format-List
Algorithm : SHA384
Hash : 20AB1C2EE19FC96A7C66E33917D191A24E3CE9DAC99DB7C786ACCE31E559144FEAFC695C58E508E2EBBC9D3C96F21FA3
Path : C:\Users\Andris\Downloads\Contoso8_1_ENT.iso
Il suffit de changer SHA384 avec MD5.
L'exemple provient de la documentation officielle de PowerShell 5.1 .
Je suppose que cette réponse est redondante avec la réponse de Keith-Hill et l'édition de la réponse choisie, mais elle renvoie à la documentation officielle et donne un meilleur exemple. La documentation a plus d'exemples.
Cela devient un one-liner si vous téléchargez FCIV à partir de Microsoft.
Téléchargé le vérificateur d’intégrité du vérificateur de fichiers de Microsoft à partir d’ici https://support.Microsoft.com/en-us/kb/841290
Exécutez la commande suivante. J'ai eu dix fichiers à vérifier.
gci WTAM*.tar | % {.\fciv $_.Name}
Échantillon pour l’option de menu contextuel:
[HKEY_CLASSES_ROOT\*\Shell\SHA1 PS check\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command get-filehash -algorithm SHA1 '%1'"
Ajout de ma solution à la mêlée. Comme indiqué dans la réponse acceptée, Get-FileHash
est facile à utiliser avec des fichiers, mais il est possible de l'utiliser avec des chaînes:
$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))
Cela renverra un hachage MD5 pour un fichier sur un ordinateur distant:
Invoke-Command -ComputerName RemoteComputerName -ScriptBlock {
$fullPath = Resolve-Path 'c:\Program Files\Internet Explorer\iexplore.exe'
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$file = [System.IO.File]::OpenRead($fullPath)
$hash = [System.BitConverter]::ToString($md5.ComputeHash($file))
$hash -replace "-", ""
$file.Dispose()
}
Joli exemple d'impression tentant de vérifier l'empreinte digitale SHA256 de la version téléchargée de gpg4win v3.0.3 à l'aide de powershell v4 (requiert Get-FileHash
)
Téléchargez le package à partir de https://www.gpg4win.org/download.html , ouvrez powershell, récupérez le hachage à partir de la page de téléchargement et exécutez:
cd ${env:USERPROFILE}\Downloads
$file="gpg4win-3.0.3.exe"
# set $hash to the hash reference from the download page:
$hash="477f56212ee60cc74e0c5e5cc526cec52a069abff485c89c2d57d1b4b6a54971"
# if you have an MD5 hash: # $hashAlgo="MD5"
$hashAlgo="SHA256"
$computed_hash=(Get-FileHash -Algorithm $hashAlgo $file).Hash.ToUpper()
if ( $computed_hash.CompareTo($hash.ToUpper()) -eq 0 ) { Write-Output "Hash matches for file $file" } else { Write-Output ( "Hash DOES NOT match for file {0}:`nOriginal hash: {1} `nComputed hash: {2}" -f ( $file, $hash.ToUpper(), $computed_hash ) ) }
Sortie:
Hash matches for file gpg4win-3.0.3.exe
Voici un exemple de commande en ligne avec à la fois le calcul de la somme de contrôle appropriée du fichier fichier, comme vous venez de le télécharger, et sa comparaison avec la somme de contrôle publiée de l'original.
Par exemple, j'ai écrit un exemple pour les téléchargements du projet Apache Jmeter . Dans ce cas, vous avez:
3a84491f10fb7b147101cf3926c4a855 * Apache-jmeter-4.0.Zip
Ensuite, en utilisant cette commande powershell, vous pouvez vérifier l’intégrité du fichier téléchargé:
PS C:\Distr> (Get-FileHash .\Apache-jmeter-4.0.Zip -Algorithm MD5).Hash -eq (Get-Content .\Apache-jmeter-4.0.Zip.md5 | Convert-String -Example "hash path=hash")
Sortie:
True
Explication:
Le premier opérande de l'opérateur -eq
est le résultat du calcul de la somme de contrôle du fichier:
(Get-FileHash .\Apache-jmeter-4.0.Zip -Algorithm MD5).Hash
Le deuxième opérande est la valeur de somme de contrôle publiée. Nous obtenons d’abord le contenu du fichier.md5 qui est une chaîne, puis nous extrayons la valeur de hachage à partir du format de chaîne:
Get-Content .\Apache-jmeter-4.0.Zip.md5 | Convert-String -Example "hash path=hash"
Fichier et fichier.md5 doivent tous deux se trouver dans le même dossier pour que cette commande fonctionne.