PowerShell에서 MD5 체크섬을 얻는 방법


답변:


326

내용이 문자열 인 경우 :

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

내용이 파일 인 경우 :

$someFilePath = "C:\foo.txt"
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($someFilePath)))

PowerShell 버전 4부터는 Get-FileHashcmdlet 을 사용하여 즉시 사용 가능한 파일을 쉽게 수행 할 수 있습니다 .

Get-FileHash <filepath> -Algorithm MD5

이것은 주석에서 식별 된 첫 번째 솔루션이 제공하는 문제 (스트림 사용, 닫기 및 대용량 파일 지원)를 피하기 때문에 확실히 바람직합니다.


12
Exception calling "ReadAllBytes" with "1" argument(s): "The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size."Powershell을 처음 접하는 Linux 사용자는 md5 합계를 얻는 데 어려움을 겪고 있습니다 md5sum file.ext. 이는 단순히 Linux 에서만 가능 합니다.
StockB

@StockB Keith의 대답은 아마도 이것을 더 잘 처리 할 것입니다. powershell에는 몇 가지 단점이 있습니다.
vcsjones

5
확장 프로그램없이 바닐라 PowerShell을 설치 했으므로 대신 명령 줄 md5sum 복제본을 다운로드하여 다운로드하면 효과적입니다. 나는 Microsoft의 것을 좋아하고 싶지만 나는 할 수 없습니다.
StockB

23
@StockB vcsjones의 메소드는 버퍼링되지 않습니다 ... = 대용량 파일에 매우 많은 메모리를 요구합니다. 난 당신이 스트림 작업 제안 : $hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)))이 당신에게 제공 낮은 메모리 사용량어떤 한계는 2GB .
Davor Josipovic

20
@davor는 일정 시간 동안 스트림을 열린 상태로 유지하므로 Powershell이 ​​닫힐 때까지 파일을 삭제할 수 없습니다. $stream = [System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)다음 $hash = [System.BitConverter]::ToString($md5.ComputeHash($stream))다음$stream.Close()
조 Amenta

57

PowerShell 커뮤니티 확장을 사용하는 경우 이를 쉽게 수행 할 수있는 Get-Hash 커맨드 렛이 있습니다.

C:\PS> "hello world" | Get-Hash -Algorithm MD5


Algorithm: MD5


Path       :
HashString : E42B054623B3799CB71F0883900F2764

10
Get-Hash는 PowerShell Community Extensions에서 제공됩니다. 패키지를 사용할 수 없거나 사용하지 않을 때는 Get-FileHashvanilla PowerShell 4.0에 cmdlet 을 추가했습니다 . Vide TechNet .
Tomasz Cudziło

이것 (그리고 아마도 대부분의 PS 솔루션)은 문자열을 UTF-16 (little-endian?)으로 인코딩합니다.
Christian Mann

PowerShell Community Extensions에 대한 링크는 CodePlex 아카이브로 리디렉션됩니다 (2017 년에 CodePlex 종료). 아마도 GitHub로 변경 하시겠습니까? (GitHub의에 새 마스터 위치인가?)
피터 모텐슨

16

다음은 두 줄입니다. 2 번 줄에서 "hello"를 변경하십시오.

PS C:\> [Reflection.Assembly]::LoadWithPartialName("System.Web")
PS C:\> [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("hello", "MD5")

1
이것의 결과는 내가 받아 들인 대답으로 얻은 출력과 같지 않습니다. "hello"로 바꾸는 경로에 의해 정의되는 FILE이 아닌 STRING "hello"의 해시를 계산합니까?
RobertG

1
사실, OP는 파일을 요청하지 않았고 문자열 솔루션을 찾기 위해 여기에 왔습니다
Chris F Carroll

16

다음은 상대 및 절대 경로를 처리하는 함수입니다.

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()
    }
}

위의 @davor 덕분에 ReadAllBytes () 대신 Open ()을 사용하고 finally 블록을 사용하는 제안에 @ jpmc26을 제안했습니다.


2
이 방법은 2GB보다 큰 파일을 입력 할 수 있으며 확장명이나 PowerShell 4.0이 필요하지 않기 때문에 vcsjones 및 Keith보다 IMHO가 더 좋습니다.
Chirag Bhatia-chirag64

1
Dispose호출은에 있어야 finally블록.
jpmc26

12

2003 년으로 거슬러 올라간 기본적으로 Windows에 오랫동안 설치되어 온 또 다른 기본 제공 명령은 Certutil 이며 물론 PowerShell에서도 호출 할 수 있습니다.

CertUtil -hashfile file.foo MD5

(주의 : MD5는 최대한의 견고성을 위해 모든 캡에 있어야합니다)


1
이 옵션을 FipsAlgorithmPolicy활성화 하면 좋은 옵션 입니다.
윌리엄 존 홀든

9

ComputeHash ()를 사용하는 온라인 예제가 많이 있습니다. 내 테스트는 네트워크 연결을 통해 실행할 때 이것이 매우 느리다는 것을 보여주었습니다. 아래 스 니펫은 훨씬 빠르게 실행되지만 마일리지는 다를 수 있습니다.

$md5 = [System.Security.Cryptography.MD5]::Create("MD5")
$fd = [System.IO.File]::OpenRead($file)
$buf = New-Object byte[] (1024*1024*8) # 8 MB 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 a hexadecimal formatted string
$hash | foreach { $hash_txt += $_.ToString("x2") }
Write-Host $hash_txt

1
당신은 다른 답변에서 2Gb의 ReadAllBytes 한계를 극복했습니다.
Jay

write-progress라인 의 백틱은 무엇을 합니까? 구문 강조 표시가 마음에 들지 않는 것 같습니다.
mwfearnley

1
@mwfearnley backtick는 줄 연속을 가능하게합니다. blogs.technet.microsoft.com/heyscriptingguy/2015/06/19/…
cmcginty

6

이 사이트의 예는 다음과 같습니다. MD5 체크섬에 Powershell 사용 있습니다. .NET 프레임 워크를 사용하여 MD5 해시 알고리즘의 인스턴스를 인스턴스화하여 해시를 계산합니다.

다음은 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()

1
읽기 전용 파일에서는 작동하지 않는 것이 좋습니다! $ stream = New-Object가 필요합니다. System.IO.FileStream ($ Path, [System.IO.FileMode] :: Open, [System.IO.FileAccess] :: Read)
Stephen Connolly

1
연결이 끊어지면 대답은 매우 쓸모가 없습니다. stackoverflow.com/help/how-to-answer
저는 Monica와 함께합니다.

1
내가 추측 한 것은 귀하의 공감 율에 대한 응답으로 여기 기사의 코드를 잘라 붙여 넣었습니다. 작년에는 표절이라고 생각했기 때문에 그렇게하지 않았습니다. Stephen의 읽기 전용 적응을 추가하면 게시 할 가치가 있다고 생각했습니다.
neontapir

@neontapir는 단지 말하기 : 소스를 인정하지 않으면 말 그대로 (또는 적응으로) 게시하는 것은 표절 일뿐입니다. 저작권 (법적 또는 도덕적)은 별도의 문제이지만 대부분의 코드 스 니펫에서 걱정하지는 않습니다.
mwfearnley

6

허용 된 답변에 명시된 것처럼 Get-FileHash파일과 함께 사용하기 쉽지만 문자열과 함께 사용할 수도 있습니다.

$s = "asdf"
Get-FileHash -InputStream ([System.IO.MemoryStream]::New([System.Text.Encoding]::ASCII.GetBytes($s)))

5

이제 매우 편리한 Get-FileHash 함수가 있습니다.

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

로 변경 SHA384하십시오 MD5.

이 예제는 PowerShell 5.1의 공식 문서에 있습니다. 이 문서에는 더 많은 예제가 있습니다.



3

PowerShell One-Liners (문자열에서 해시로)

MD5

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA1

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA256

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA384

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

SHA512

([System.BitConverter]::ToString((New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider).ComputeHash((New-Object -TypeName System.Text.UTF8Encoding).GetBytes("Hello, World!")))).Replace("-","")

1

원격 컴퓨터의 파일에 대한 MD5 해시를 반환합니다.

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()
}

1

마우스 오른쪽 버튼 클릭 메뉴 옵션 샘플 :

[HKEY_CLASSES_ROOT\*\shell\SHA1 PS check\command]
@="C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -NoExit -Command Get-FileHash -Algorithm SHA1 '%1'"

0

다음은 SHA256 지문을 확인하려는 인쇄 예제입니다. PowerShell v4를 사용하여 gpg4win v3.0.3을 다운로드했습니다 (필수 Get-FileHash).

https://www.gpg4win.org/download.html 에서 패키지를 다운로드하고 PowerShell을 열고 다운로드 페이지에서 해시를 가져온 후 다음을 실행하십시오.

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

산출:

Hash matches for file gpg4win-3.0.3.exe

0

다음은 방금 다운로드 한 것처럼 파일 의 올바른 체크섬을 계산 하고 원본의 게시 된 체크섬과 비교 하는 한 줄 명령 예제입니다 .

예를 들어 Apache JMeter 프로젝트에서 다운로드 하는 예제를 작성했습니다 . 이 경우에는 다음이 있습니다.

  1. 다운로드 된 이진 파일
  2. file.md5 에 다음 형식으로 하나의 문자열로 게시 된 원본의 체크섬 :

3a84491f10fb7b147101cf3926c4a855 * apache-jmeter-4.0.zip

그런 다음이 PowerShell 명령을 사용하여 다운로드 한 파일의 무결성을 확인할 수 있습니다.

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

산출:

True

설명:

-eq연산자 의 첫 번째 피연산자 는 파일의 체크섬을 계산 한 결과입니다.

(Get-FileHash .\apache-jmeter-4.0.zip -Algorithm MD5).Hash

두 번째 피연산자는 게시 된 체크섬 값입니다. 먼저 하나의 문자열 인 file.md5의 내용을 가져온 다음 문자열 형식에 따라 해시 값을 추출합니다.

Get-Content .\apache-jmeter-4.0.zip.md5 | Convert-String -Example "hash path=hash"

파일file.md5는 이 명령 작업 동일한 폴더에 있어야합니다.


0

이것이 일관된 해시 값을 얻는 데 사용하는 것입니다.

function New-CrcTable {
    [uint32]$c = $null
    $crcTable = New-Object 'System.Uint32[]' 256

    for ($n = 0; $n -lt 256; $n++) {
        $c = [uint32]$n
        for ($k = 0; $k -lt 8; $k++) {
            if ($c -band 1) {
                $c = (0xEDB88320 -bxor ($c -shr 1))
            }
            else {
                $c = ($c -shr 1)
            }
        }
        $crcTable[$n] = $c
    }

    Write-Output $crcTable
}

function Update-Crc ([uint32]$crc, [byte[]]$buffer, [int]$length, $crcTable) {
    [uint32]$c = $crc

    for ($n = 0; $n -lt $length; $n++) {
        $c = ($crcTable[($c -bxor $buffer[$n]) -band 0xFF]) -bxor ($c -shr 8)
    }

    Write-Output $c
}

function Get-CRC32 {
    <#
        .SYNOPSIS
            Calculate CRC.
        .DESCRIPTION
            This function calculates the CRC of the input data using the CRC32 algorithm.
        .EXAMPLE
            Get-CRC32 $data
        .EXAMPLE
            $data | Get-CRC32
        .NOTES
            C to PowerShell conversion based on code in https://www.w3.org/TR/PNG/#D-CRCAppendix

            Author: Øyvind Kallstad
            Date: 06.02.2017
            Version: 1.0
        .INPUTS
            byte[]
        .OUTPUTS
            uint32
        .LINK
            https://communary.net/
        .LINK
            https://www.w3.org/TR/PNG/#D-CRCAppendix

    #>
    [CmdletBinding()]
    param (
        # Array of Bytes to use for CRC calculation
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [byte[]]$InputObject
    )

    $dataArray = @()
    $crcTable = New-CrcTable
    foreach ($item  in $InputObject) {
        $dataArray += $item
    }
    $inputLength = $dataArray.Length
    Write-Output ((Update-Crc -crc 0xffffffffL -buffer $dataArray -length $inputLength -crcTable $crcTable) -bxor 0xffffffffL)
}

function GetHash() {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$InputString
    )

    $bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString)
    $hasCode = Get-CRC32 $bytes
    $hex = "{0:x}" -f $hasCode
    return $hex
}

function Get-FolderHash {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$FolderPath
    )

    $FolderContent = New-Object System.Collections.ArrayList
    Get-ChildItem $FolderPath -Recurse | Where-Object {
        if ([System.IO.File]::Exists($_)) {
            $FolderContent.AddRange([System.IO.File]::ReadAllBytes($_)) | Out-Null
        }
    }

    $hasCode = Get-CRC32 $FolderContent
    $hex = "{0:x}" -f $hasCode
    return $hex.Substring(0, 8).ToLower()
}

PowerShell 코드를 어디에서 복사 했습니까? https://communary.net/ ?
피터 Mortensen

0

주어진 문자열에 대해 MD5를 얻는 데 사용하는 스 니펫은 다음과 같습니다.

$text = "text goes here..."
$md5  = [Security.Cryptography.MD5CryptoServiceProvider]::new()
$utf8 = [Text.UTF8Encoding]::UTF8
$bytes= $md5.ComputeHash($utf8.GetBytes($text))
$hash = [string]::Concat($bytes.foreach{$_.ToString("x2")}) 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.