PowerShell을 사용하여 인증서 저장소 관리

Marion Paul Kenneth Mendoza 2023년6월20일
  1. 인증서 저장소 이해
  2. PowerShell을 사용하여 인증서 관리
PowerShell을 사용하여 인증서 저장소 관리

우리가 Windows 시스템 관리자라면 Windows 인증서로 작업해야 했을 수도 있습니다. 안타깝게도 Windows에서 인증서 작업은 일반적으로 시스템 관리자가 수행해야 하는 다양한 작업 중 하나입니다.

이 문서에서는 PowerShell을 사용하여 인증서를 쿼리하고 인증서 저장소를 관리하는 방법에 대해 설명합니다.

인증서 저장소 이해

인증서 저장소는 Windows OS가 현재 설치된 모든 인증서를 보관하는 “버킷"입니다. 인증서는 여러 저장소에 존재할 수 있으며 물리적 또는 논리적 저장소라고도 합니다. 레지스트리 키와 파일은 기존 파일 시스템 또는 레지스트리 위치를 참조하는 물리적 저장소에 저장됩니다.

Windows 레지스트리와 파일 시스템에는 각 저장소가 포함되어 있습니다. 인증서로 작업할 때 레지스트리나 파일 시스템이 아닌 논리 저장소와 상호 작용합니다.

하나 이상의 물리적 저장소에 대한 동적 참조는 논리적 저장소이며 물리적 저장소는 논리적 저장소보다 관리하기 더 어렵습니다. Windows는 사용자 컨텍스트와 컴퓨터 컨텍스트의 두 위치에 인증서를 보관합니다.

단일 사용자, 여러 사용자 또는 시스템 자체에서 인증서를 사용해야 하는지 여부에 따라 인증서는 이 두 컨텍스트 중 하나에 배치됩니다. 이 문서의 나머지 부분에서는 사용자 또는 컴퓨터 컨텍스트의 인증서를 사용자 인증서 및 컴퓨터 인증서라고 합니다.

사용자 인증서

단일 사용자만 인증서를 사용하도록 하려면 Windows 인증서 관리자에 저장된 사용자 인증서가 이상적입니다. 이는 유선 IEEE 802.1x와 같은 인증서 기반 인증 시스템에서 일반적입니다.

사용자 인증서는 현재 사용자의 프로필에 저장되며 해당 사용자의 컨텍스트에만 논리적으로 매핑될 수 있습니다. 동일한 시스템에서도 사용자 인증서는 “매핑"되고 각 사용자에게 고유합니다.

컴퓨터 인증서

모든 사용자가 컴퓨터 또는 시스템 프로세스에서 인증서를 사용하는 경우 컴퓨터 컨텍스트의 저장소 내에 배치해야 합니다. 예를 들어 시스템이 웹 서버의 인증서를 사용하여 모든 클라이언트에 대한 통신을 암호화하는 경우 컴퓨터 컨텍스트의 저장소에 인증서를 설정하는 것이 이상적입니다.

우리는 컴퓨터의 인증서 저장소가 모든 사용자 컨텍스트에 대해 논리적으로 매핑되고 이 개념을 통해 컴퓨터 인증서 저장소의 인증서를 모든 사용자가 사용할 수 있음을 볼 수 있습니다. 그러나 여전히 개인 키에 대해 구성된 권한에 따라 달라집니다.

Program Data 폴더와 Local Machine Registry 하이브에는 컴퓨터 인증서가 포함되어 있습니다. 또한 AppData 폴더와 Current User Registry 하이브에서 사용자 인증서를 찾을 수 있습니다.

PowerShell을 사용하여 인증서 관리

MMC와 마찬가지로 PowerShell을 사용하여 인증서를 보고 관리할 수도 있습니다. 그러나 먼저 실제 저장소(레지스트리 및 파일 시스템)에서 인증서를 검사해 보겠습니다.

실제 매장

Get-ChildItem PowerShell cmdlet을 사용하여 상위 HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates\ 레지스트리 키 경로 내의 모든 키와 값을 열거할 수 있습니다.

아래 명령은 중간 인증 기관 논리 저장소에서 현재 로그인한 사용자의 모든 인증서를 열거합니다.

예제 코드:

Get-ChildItem -Path HKCU:\Software\Microsoft\SystemCertificate\CA\Certificates\

신뢰할 수 있는 CA에 대한 인증서의 지문과 해당 속성의 인증서는 우리가 보는 레지스트리 하이브의 각 항목에 해당합니다.

출력:

Hive: HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\CA\Certificates

Name                           Property
----                           --------
070A726C6E4418DCF0213874F0C16D Blob : {3, 0, 0, 0...}
93B041E935
104C63D2546B8021DD105E9FBA5A8D Blob : {3, 0, 0, 0...}
78169F6B32
<SNIP>

개인 저장소는 또 다른 표준 저장소이며 이 저장소의 인증서는 레지스트리가 아닌 파일 시스템에 저장됩니다. 아래 명령은 개인 현재 사용자 저장소에 설치된 인증서에 해당하는 파일이 포함된 디렉터리를 반환합니다.

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificate\My\Certificates\

아래 명령에서 반환되는 각 파일은 KSP(Key Storage Provider)에서 생성한 개인 키에 대한 개체를 참조합니다. 파일 이름은 인증서의 주체 키 식별자에 해당합니다.

따라서 우리가 설치하는 각 개인 키에는 해당 파일이 추가됩니다.

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificate\My\Keys\

아래 명령으로 생성된 디렉터리의 각 파일은 KSP의 암호화된 개인 키에 대한 고유한 컨테이너입니다. 파일 이름과 인증서에는 직접 링크가 없지만 파일은 이전 명령에서 포인터의 대상입니다.

Get-ChildItem -Path $env:APPDATA\Microsoft\Crypto\Keys

논리적 저장소

물리적 경로에서 인증서로 작업하는 것은 일반적이지 않기 때문에 나머지 인스턴스에 대해 논리적 스토리지를 사용합니다. PowerShell은 인증서를 물리적 저장소에 매핑하는 Cert:PSDrive를 사용하여 논리 저장소에 액세스할 수 있습니다.

인증서로 작업할 때 특정 작업을 수행하기 위해 자격 증명을 필터링하고 선택하는 방법이 필요합니다. 예를 들어 특정 확장의 값을 기준으로 인증서를 선별하고 선택합니다.

다음 예제에서는 루트 CA 저장소에 설치된 모든 인증서를 나열하는 것으로 시작해야 합니다.

Get-ChildItem -Path Cert:\CurrentUser\Root\

반환된 개체는 아래 예제에서 활용할 수 있는 인증서 개체입니다. 인증서 개체에는 이미 공통 확장자가 속성으로 있습니다.

따라서 Get-Member를 사용하여 아래 예제에서 반환된 개체의 모든 속성을 나열합니다.

예제 코드:

# gci is an alias of Get-ChildItem
gci -Path Cert:\CurrentUser\Root | Get-Member -MemberType Properties

출력:

TypeName: System.Security.Cryptography.X509Certificates.X509Certificate2

Name                     MemberType     Definition
----                     ----------     ----------
PSChildName              NoteProperty   string PSChildName=EBE112F56D5FE0BA23289319C89D7784A10CEB61
PSDrive                  NoteProperty   PSDriveInfo PSDrive=Cert
PSIsContainer            NoteProperty   bool PSIsContainer=False
<SNIP>

출력에서 볼 수 있듯이 다양한 확장이 우리가 찾는 인증서를 찾는 데 도움이 됩니다. 확장에는 인증서가 부여된 사람, 용도 등 인증서에 대한 세부 정보가 포함됩니다.

더 복잡한 사용 사례에서 활용되는 인증서 템플릿과 같은 다른 확장이 있는 인증서를 찾아야 합니다. 문제는 이러한 확장의 값이 정수 배열로 반환되고 이러한 정수가 ASN.1 인코딩 콘텐츠를 나타낸다는 것입니다.

이 관계를 확인하기 위해 아래 명령에서 키 사용을 수동으로 가져옵니다.

((gci -Path Cert:\CurrentUser\Root\ | select -First 1).Extensions | Where-Object {$_.Oid.FriendlyName -eq "Key Usage"}).format($true)

ASN.1 디코딩을 수행하는 형식 방법은 위의 지침에서 소개하는 새로운 부분입니다. 위의 부울 값(예: $true)을 전달하여 반환된 객체를 한 줄로 할지 여러 줄로 할지 지정합니다.

아래 명령에서 인증서의 지문 값을 활용합니다. 지문 값은 Windows PowerShell 변수로 설정되며 다음 명령에서 적절한 인증을 선택하는 데 사용됩니다.

$thumb = "cdd4eeae6000ac7f40c3802c171e30148030c072"
Get-ChildItem -Path Cert:\CurrentUser\Root\ | Where-Object {$_.Thumbprint -eq $thumb}
Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn