PowerShell 스크립트 서명하기 (효과적으로 실행하는 방법)

필요한 사람이 스크립트를 수정하지 않고 원본으로 통과하도록 보장해야 하는가요? 그렇다면 PowerShell 스크립트에 서명하는 방법을 배워야 합니다. 서명은 스크립트에 발행자의 신원을 추가하여 사용자가 스크립트 소스를 신뢰할지 여부를 결정할 수 있도록 합니다.

이 기사에서는 PowerShell 스크립트에 서명하는 방법을 배우고 환경에서 신뢰할 수 있는 스크립트만 실행되도록 보장하는 방법을 배웁니다.

필수 사항

이 기사의 예제를 따르려면 다음이 필요합니다.

  • A computer running on a recent version of the Windows operating system. This article uses Windows 10 version 20H2.
  • Windows PowerShell 5.1 또는 PowerShell 6+. 이 기사의 예제는 PowerShell v7.1.3을 사용합니다.
  • A sample PowerShell script for signing. Feel free to create a script with any name and in any folder you want. This article will use a sample script called C:\ATA\myscript.ps1 that contains the code below.
Write-Host "Script Execution - OK"

코드 서명 인증서 획득

PowerShell 스크립트에 서명하는 방법을 배우기 전에 먼저 코드 서명 인증서를 획득해야 합니다. Microsoft 세계에서 코드 서명 인증서는 Authenticode 인증서로도 알려져 있습니다.

A code signing certificate is one type of digital certificate whose purpose for signing files. Signing a file or code with a code signing certificate adds proof that the file came from the publisher who signed it.

서명된 스크립트를 배포하거나 배포할 위치에 따라 코드 서명 인증서를 얻는 곳이 달라집니다. 그리고 항상 비용도 큰 요소입니다.

  • 글로벌 / 공개 – 발급 기관이 전 세계에서 신뢰하는 인증 기관 (CA)에서 발급한 인증서가 필요합니다. 이러한 CA의 예로는 GeoTrustDigiCert가 있습니다. 이러한 인증서는 무료가 아닙니다. 예를 들어 DigiCert Authenticode 인증서는 이 글을 작성하는 시점 기준으로 연간 $474에 구매할 수 있습니다.
  • 내부 / 로컬 인트라넷 – 내부 인증 기관 (CA) 서버가 있는 경우 내부 CA 서버에서 서명 인증서를 요청하고 다운로드할 수 있습니다.
  • 개인 / 개발 – 개인 테스트 또는 개발용으로는 자체 서명된 인증서가 적합합니다. 이 유형의 서명 인증서는 이 문서에서 사용할 것입니다.

코드 서명을 위한 자체 서명된 인증서 생성

이전 섹션에서 PowerShell 스크립트에 서명하는 방법을 읽었으므로 먼저 코드 서명 인증서가 필요합니다. 이 튜토리얼에서는 개인 테스트만 수행하므로 자체 서명된 인증서가 충분합니다. 그러나 어디서 얻을 수 있을까요?

자체 서명은 이름대로 로컬 컴퓨터가 자체에게 코드 서명 인증서를 발급한다는 것을 의미합니다. 자체 서명된 인증서를 생성하려면 다음 단계를 따르십시오.

1. 컴퓨터에서 PowerShell을 관리자 권한으로 엽니다.

2. 아래 명령을 복사하여 PowerShell에서 실행합니다. 이 명령은 New-SelfSignedCertificate cmdlet을 사용하여 새로운 코드 서명 인증서를 생성합니다. 인증서의 이름은 로컬 컴퓨터의 개인 인증서 저장소 내에 ATA Authenticode입니다.

New-SelfSignedCertificate cmdlet은 현재 사용자의 개인 인증서 저장소(cert:\CurrentUser\My) 또는 로컬 컴퓨터의 개인 인증서 저장소(cert:\LocalMachine\My)에서만 인증서를 생성하는 데 사용됩니다. cert:\LocalMachine\My의 인증서는 컴퓨터 전체에서 사용할 수 있습니다.

이 명령은 또한 새로운 단계에서 사용하기 위해 인증서 개체를 $authenticode 변수에 저장합니다.

# 로컬 컴퓨터의 개인 인증서 저장소에 자체 서명 Authenticode 인증서 생성.
 $authenticode = New-SelfSignedCertificate -Subject "ATA Authenticode" -CertStoreLocation Cert:\LocalMachine\My -Type CodeSigningCert

3. 이제 새로 생성한 인증서를 컴퓨터가 신뢰하도록 만들려면, 자체 서명 인증서를 컴퓨터의 신뢰할 수 있는 루트 인증 기관신뢰할 수 있는 배포자 인증서 저장소에 추가합니다. 이를 위해 아래 코드를 복사하여 PowerShell에서 실행하십시오.

# 컴퓨터의 루트 인증서 저장소에 자체 서명된 Authenticode 인증서 추가합니다.
## LocalMachine\Root 인증서 저장소를 나타내는 개체를 만듭니다.
 $rootStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("Root","LocalMachine")
## 읽기 및 쓰기용으로 루트 인증서 저장소를 엽니다.
 $rootStore.Open("ReadWrite")
## $authenticode 변수에 저장된 인증서를 추가합니다.
 $rootStore.Add($authenticode)
## 루트 인증서 저장소를 닫습니다.
 $rootStore.Close()
 
# 컴퓨터의 신뢰할 수 있는 발행자 인증서 저장소에 자체 서명된 Authenticode 인증서를 추가합니다.
## LocalMachine\TrustedPublisher 인증서 저장소를 나타내는 개체를 만듭니다.
 $publisherStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPublisher","LocalMachine")
## 읽기 및 쓰기용으로 TrustedPublisher 인증서 저장소를 엽니다.
 $publisherStore.Open("ReadWrite")
## $authenticode 변수에 저장된 인증서를 추가합니다.
 $publisherStore.Add($authenticode)
## TrustedPublisher 인증서 저장소를 닫습니다.
 $publisherStore.Close()

자체 서명된 인증서를 세 가지 다른 인증서 저장소에 설치하는 주요 이유가 세 가지 있습니다.

  • 개인 인증서 저장소에 생성한 인증서는 코드 서명 인증서로 사용됩니다.
  • 동일한 인증서를 신뢰할 수 있는 발행자 저장소에 복사하면 로컬 컴퓨터가 스크립트를 서명한 발행자를 신뢰합니다. PowerShell은 스크립트 서명을 유효성 검사하기 위해 이 저장소에서 인증서를 확인합니다.
  • 마침내, 신뢰할 수 있는 루트 인증 기관에 자체 서명된 인증서를 추가하면 로컬 컴퓨터가 개인신뢰할 수 있는 발행자 저장소의 인증서를 신뢰합니다.

4. 주제가 ATA Authenticode인 인증서가 개인, 루트, 및 신뢰할 수 있는 발행자 인증서 저장소에 있는지 확인하려면 PowerShell에서 아래 명령을 실행합니다.

# 컴퓨터의 개인 인증서 저장소에 자체 서명된 Authenticode 인증서가 있는지 확인
 Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# 컴퓨터의 루트 인증서 저장소에 자체 서명된 Authenticode 인증서가 있는지 확인
 Get-ChildItem Cert:\LocalMachine\Root | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# 컴퓨터의 신뢰할 수 있는 발행자 인증서 저장소에 자체 서명된 Authenticode 인증서가 있는지 확인
 Get-ChildItem Cert:\LocalMachine\TrustedPublisher | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
Confirming the creation of the new self-signed certificate

5. 대신 GUI에서 인증서를 보려면 인증서 스냅인을 열고 인증서 폴더 내에서 생성한 인증서를 개인, 신뢰할 수 있는 루트 인증 기관,신뢰할 수 있는 발행자 인증서 저장소에서 찾습니다.

Viewing certificates in the Microsoft Management Console (MMC)

PowerShell 스크립트에 서명하는 방법

이제 코드 서명 인증서를 만들고 설치했으므로 샘플 PowerShell 스크립트에 서명할 준비가되었습니다. 스크립트에 서명해야하는 경우 Set-AuthenticodeSignature cmdlet이 주요 기능입니다.

PowerShell 스크립트에 서명하려면 PowerShell에서 아래 코드를 실행하십시오. 첫 번째 명령은 로컬 컴퓨터의 개인 인증서 저장소에서 코드 서명 인증서를 가져옵니다. 두 번째 명령은 PowerShell 스크립트 파일에 디지털 서명을 추가합니다.

# 로컬 컴퓨터의 인증서 저장소에서 이름이 *ATA Authenticode*인 코드 서명 인증서를 가져 와 $codeCertificate 변수에 저장합니다.
$codeCertificate = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}

# PowerShell 스크립트에 서명
# 매개 변수:
# FilePath - 서명 할 PowerShell 스크립트의 파일 경로를 지정합니다. 예: C:\ATA\myscript.ps1.
# Certificate - 스크립트 서명에 사용할 인증서를 지정합니다.
# TimeStampServer - 스크립트의 디지털 서명에 타임 스탬프를 추가하는 신뢰할 수있는 타임 스탬프 서버를 지정합니다. 타임 스탬프를 추가하면 서명 인증서가 만료 될 때 코드가 만료되지 않음을 보장합니다.
Set-AuthenticodeSignature -FilePath C:\ATA\myscript.ps1 -Certificate $codeCertificate -TimeStampServer *<http://timestamp.digicert.com>*

가장 신뢰할 수 있는 인증서 제공업체는 타임스탬프 서버를 보유하고 있으며 해당 제공업체 웹사이트에서 확인할 수 있습니다. 예를 들어, DigiCert의 타임스탬프 서버는 http://timestamp.digicert.com이고 Comodo는 http://timestamp.comodoca.com을 가지고 있습니다.

스크립트에 서명한 후에는 아래 스크린샷과 유사한 출력물을 볼 수 있어야 합니다.

How to Sign PowerShell Scripts

PowerShell 스크립트의 디지털 서명 확인

지금까지는 만들어 둔 자체 서명된 인증서를 사용하여 PowerShell 스크립트에 서명했습니다. 그러나 스크립트에 디지털 서명이 있는지 어떻게 확인할 수 있을까요?

코드 열기

스크립트의 디지털 서명을 확인하는 한 가지 방법은 스크립트를 열고 텍스트 편집기에서 코드를 확인하는 것입니다. 예를 들어, 서명된 스크립트는 코드의 끝 부분에 서명 블록이 있습니다. 서명 블록은 # SIG # Begin signature block으로 시작하여 # SIG # End signature block으로 끝납니다.

Viewing the digital signature in the script’s content

스크립트의 코드에서 디지털 서명 블록을 삭제하면 스크립트가 서명되지 않은 상태로 돌아갑니다.

스크립트 파일 속성 열기

스크립트의 디지털 서명을 확인하는 또 다른 방법은 Windows 탐색기에서 스크립트 파일 속성을 열어보는 것입니다. 이를 위해서는:

  1. Windows Explorer에서 PowerShell 스크립트의 위치로 이동합니다. 이 예에서는 스크립트가 C:\ATA\myscript.ps1에 있습니다.
  2. 스크립트를 마우스 오른쪽 버튼으로 클릭하고 속성을 클릭합니다.
  3. 파일의 속성 창에서 디지털 서명 탭을 클릭하면 서명 목록 아래에 디지털 서명이 표시됩니다.
Viewing the digital signature in the script’s file properties

Get-AuthenticodeSignature을 사용하여

PowerShell 내부에서 스크립트 서명을 확인할 수 있다는 것에 놀랄 것이 있나요? 아마도 아닐 것입니다. 파일의 서명을 검색하려면 호출할 수 있는 cmdlet은 Get-AuthenticodeSignature입니다.

스크립트의 디지털 서명을 얻으려면 아래 명령을 실행하십시오. 이 명령은 C:\ATA\myscript.ps1 파일의 서명을 가져옵니다. Select-Object -Property * cmdlet은 서명의 모든 세부 정보를 표시합니다.

Get-AuthenticodeSignature -FilePath C:\\ATA\\myscript.ps1 | Select-Object -Property *

명령을 실행한 후에는 아래 스크린샷과 유사한 결과가 표시됩니다. 보시다시피, SignerCertificate 속성에는 서명 인증서의 세부 정보가 표시됩니다. TimerStamperCertificate 속성에는 타임스탬프 서버의 인증서가 표시됩니다.

Viewing the digital signature in PowerShell

서명된 PowerShell 스크립트 실행

이 시점에서 PowerShell 스크립트에 서명을 하고 디지털 서명이 있는지 확인했습니다. 그러나 모든 단계를 올바르게 수행했는지의 궁극적인 테스트는 스크립트를 실행하고 작동하는지 확인하는 것입니다.

PowerShell에는 사용자가 스크립트를 실수로 실행하지 않도록 보호하는 안전 기능이 있습니다. 이 안전 기능은 Execution Policies.라고 불립니다. 실행 정책에 따라 PowerShell은 스크립트 실행을 방지하거나 허용할 수 있습니다.

다양한 실행 정책 및 이들이 스크립트 실행에 미치는 영향에 대한 자세한 내용은 PowerShell Execution Policies: Understanding and Managing을 참조하세요.

서명된 PowerShell 스크립트를 실행하려면 다음 단계를 따르세요.

먼저 실행 정책을 AllSigned로 변경하여 서명된 스크립트만 실행될 수 있도록 합니다. 이 단계를 수행하지 않으면 서명된 스크립트가 올바르게 작동하는지 정확하게 테스트할 수 없습니다. 이를 위해 PowerShell을 관리자 권한으로 실행하여 아래 명령을 실행하여 Set-ExecutionPolicy cmdlet을 호출하세요.

Set-ExecutionPolicy AllSigned

다음으로 서명된 PowerShell 스크립트를 실행하세요.

C:\ATA\myscript.ps1

스크립트는 아래 결과에서 볼 수 있듯이 오류나 경고 없이 실행되어야 합니다.

Running the signed script without errors

그러나 스크립트가 올바르게 서명되지 않았거나 전혀 서명되지 않은 경우 아래 이미지와 유사한 오류가 발생합니다. 이 경우 단계를 다시 확인하고 스크립트에 서명을 다시 시도하십시오.

Running a script with errors regarding the digital signature

스크립트를 최종적으로 업데이트했다면 어떻게 되는가요? 디지털 서명은 여전히 유효할까요? 답은 아닙니다. 서명된 스크립트에 대한 수정은 스크립트의 디지털 서명을 무효화합니다. 수정된 스크립트를 실행하면 오류가 발생하여 실패합니다.

수정된 서명된 스크립트를 테스트하려면 다음 단계를 따르십시오.

1. 서명된 myscript.ps1 스크립트를 코드 또는 텍스트 편집기에서 엽니다.

2. 코드를 수정하여 이 예제에서 밑줄과 같은 문자를 추가합니다. 다른 내용은 변경하지 마십시오.

Editing the signed script

3. 코드를 수정한 후 스크립트를 저장합니다.

4. 마지막으로 수정된 스크립트를 PowerShell에서 아래 명령을 실행하여 실행합니다.

C:\ATA\myscript.ps1

스크립트를 수정했으므로 스크립트를 실행하면 아래와 같은 오류가 발생합니다. 디지털 서명을 업데이트하고 수정하려면 스크립트에 다시 서명해야 합니다.

Running a signed script with a broken digital signature

A digital signature does not guarantee that nobody modified the script from its original version. Any PowerShell script with malicious code may be digitally signed, too. Always practice caution when running scripts from sources you do not fully trust.

결론

이 기사에서는 실행 정책에 따라 PowerShell 스크립트에 서명하는 이유를 배웠습니다. 또한 서명된 스크립트와 서명되지 않은 스크립트를 구별하는 방법을 배웠습니다. 마지막으로 PowerShell 스크립트에 디지털 서명하는 방법과 해당 스크립트를 테스트하고 실행하는 방법을 배웠습니다.

지금 PowerShell 스크립트에 서명하는 방법을 알았으니, 배포하거나 배포하기 전에 스크립트에 서명을 시작하시겠습니까?

Source:
https://adamtheautomator.com/how-to-sign-powershell-script/