Computer >> 컴퓨터 >  >> 시스템 >> Windows 7

Windows에서 서명되지 않은 장치 드라이버에 서명하는 방법 (자체 서명 인증서 활용 가이드)

기본적으로 모든 64비트 Windows 버전은 유효한 디지털 서명이 없는 장치 드라이버의 설치를 차단합니다. 서명되지 않은 드라이버는 운영체제에 의해 자동으로 거부되는데, 디지털 서명은 해당 드라이버가 신뢰할 수 있는 개발자나 벤더가 배포했으며 코드가 변조되지 않았음을 보증하는 역할을 합니다.

Windows에서 서명되지 않은 드라이버의 서명 확인을 비활성화하는 방법은 여러 가지가 있습니다(GPO 사용, 테스트 부팅 모드 등). 이번 글에서는 Windows x64용 서명되지 않은 드라이버에 직접 서명하는 방법을 소개합니다(Windows 11, 10, 8.1, 7에 적용 가능).

목차

  • 자체 서명 드라이버 인증서 만들기
  • 드라이버 패키지 서명용 카탈로그 파일(CAT) 생성
  • 자체 서명 인증서로 드라이버 패키지 서명하기
  • Windows에 자체 서명 드라이버 설치하기
  • Windows의 사용자 모드와 커널 모드 드라이버

예를 들어 Windows 10 x64용으로 디지털 서명이 없는 특정 장치 드라이버가 있다고 가정해 보겠습니다. 이 예시에서는 상당히 오래된 그래픽 카드의 드라이버를 사용합니다. 벤더 웹사이트에서 해당 Windows 버전용 드라이버 아카이브를 다운로드하고(Windows Vista x64용 비디오 드라이버만 찾을 수 있었습니다), 그 내용을 c:\tools\drv1\ 폴더에 압축 해제했습니다. 내장 도구인 pnputil을 사용해 드라이버를 Windows 드라이버 저장소에 추가하며 설치를 시도해 보겠습니다.

Pnputil –a c:\tools\drv1\xg20gr.inf

참고: 이 명령과 이후의 모든 명령은 반드시 관리자 권한 명령 프롬프트에서 실행해야 합니다.

드라이버 설치 중 Windows 7에서는 운영체제가 이 드라이버의 디지털 서명을 확인할 수 없다는 경고가 표시됩니다.

Windows can't verify the publisher of this driver software.

Windows 10(21H2)에서는 이 경고가 나타나지 않지만, 대신 콘솔에 오류가 출력됩니다.

Processing inf: xg20gr.inf
Adding the driver package failed: The third-party INF does not contain digital signature information.

파일 탐색기에서 inf 드라이버 파일을 마우스 오른쪽 버튼으로 클릭하고 설치(Install)를 선택하면 다음과 같은 오류가 발생합니다.

The third-party INF does not contain digital signature information.

이제 이 드라이버에 자체 서명 인증서로 서명해 보겠습니다.

서명을 생성하고 드라이버에 서명하려면 다음 Windows 애플리케이션 개발 도구를 다운로드하여 설치해야 합니다.

  • Windows SDK(Software Development Kit) 또는 해당 Windows 버전용 Microsoft Visual Studio 2005 이상. signtool.exe가 포함된 Windows SDK Signing tools for Desktop 패키지를 설치하세요.
  • Windows Driver Kit(WDK) — https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk

팁: 이러한 도구를 설치하기 전에 컴퓨터에 .NET Framework 4가 설치되어 있는지 확인하세요.

1. 자체 서명 드라이버 인증서 만들기

시스템 드라이브 루트에 C:\DriverCert 폴더를 생성합니다.

New-SelfSignedCertificate PowerShell cmdlet을 사용하여 코드 서명 인증서를 만들 수 있습니다. 이 예시에서는 유효 기간이 3년인 자체 서명 인증서를 생성합니다.

$todaydate = Get-Date
$add3year = $todaydate.AddYears(3)
$cert = New-SelfSignedCertificate -Subject "WOSHUB" -Type CodeSigningCert -CertStoreLocation cert:\LocalMachine\My -notafter $add3year

그다음 이 인증서를 암호와 함께 pfx 파일로 내보냅니다.

$CertPassword = ConvertTo-SecureString -String "P@ss0wrd" -Force –AsPlainText
Export-PfxCertificate -Cert $cert -FilePath C:\DriverCert\myDrivers.pfx -Password $CertPassword

생성한 인증서는 자체 서명(self-signed)이므로 Windows는 기본적으로 이를 신뢰하지 않습니다. Sigcheck 유틸리티로 인증서 저장소를 확인하면, 이 인증서가 Microsoft 신뢰할 수 있는 루트 인증서 목록(주기적으로 업데이트 필요)에 등록되어 있지 않아 신뢰할 수 없음(Untrusted)으로 표시됩니다.

이제 인증서를 신뢰할 수 있는 루트 저장소(Trusted Root)와 신뢰할 수 있는 게시자(Trusted Publisher) 저장소에 추가해야 합니다.

$certFile = Export-Certificate -Cert $cert -FilePath C:\DriverCert\drivecert.cer
Import-Certificate -CertStoreLocation Cert:\LocalMachine\AuthRoot -FilePath $certFile.FullName
Import-Certificate -CertStoreLocation Cert:\LocalMachine\TrustedPublisher -FilePath $certFile.FullName

이전 버전의 Windows에서는 자체 서명 인증서를 생성할 때 Windows SDK(Software Development Kit)의 makecert.exe 도구를 사용해야 합니다. 이 경우 인증서 생성 명령은 다음과 같습니다.

cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1\bin"

예를 들어 WinOSHub 회사 이름으로 발급된 자체 서명 인증서와 개인 키를 생성합니다.

makecert -r -sv C:\DriverCert\myDrivers.pvk -n CN="WinOSHub" C:\DriverCert\myDrivers.cer

인증서 생성 과정에서 도구가 키 암호를 지정하라고 요청합니다. 여기서는 P@ss0wrd로 설정하겠습니다.

앞서 생성한 게시자 인증서의 공개 키(PKSC)를 생성합니다.

cert2spc C:\DriverCert\myDrivers.cer C:\DriverCert\myDrivers.spc

공개 키(.spc)와 개인 키(.pvk)를 개인 정보 교환(Personal Information Exchange, .pfx) 형식의 단일 인증서 파일로 결합합니다.

pvk2pfx -pvk C:\DriverCert\myDrivers.pvk -pi P@ss0wrd -spc C:\DriverCert\myDrivers.spc -pfx C:\DriverCert\myDrivers.pfx -po P@ss0wrd

인증서를 신뢰할 수 있는 저장소에 추가합니다.

certmgr.exe -add C:\DriverCert\myDrivers.cer -s -r localMachine ROOT
certmgr.exe -add C:\DriverCert\myDrivers.cer -s -r localMachine TRUSTEDPUBLISHER

AD 도메인 환경이라면 그룹 정책(Group Policy)을 통해 이 인증서를 클라이언트 컴퓨터에 중앙 집중식으로 배포할 수 있습니다.

로컬 컴퓨터 인증서 관리 스냅인(certlm.msc)을 열고 인증서가 신뢰할 수 있는 게시자(Trusted Publishers)와 신뢰할 수 있는 루트 인증 기관(Trusted Root Certification Authorities)에 포함되어 있는지 확인합니다.

참고: 인증서에는 유효 기간이 있지만, CodeSigning 인증서가 만료되었다는 것은 새 서명을 생성할 수 없다는 의미일 뿐입니다. 이 인증서로 이미 서명된 드라이버의 유효성은 무제한입니다(또는 지정된 타임스탬프 기간 동안 기존 서명이 유효합니다).

2. 드라이버 패키지 서명용 카탈로그 파일(CAT) 생성

C:\DriverCert\xg20 디렉터리를 생성하고, 원래 드라이버 아카이브를 압축 해제한 폴더(c:\tools\drv1\)의 모든 파일을 복사합니다. 이 파일들 중 확장자가 .sys.inf인 파일이 있는지 확인하세요(이 예시에서는 xg20grp.sys와 xg20gr.inf입니다).

md C:\DriverCert\xg
xcopy c:\tools\drv1\ C:\DriverCert\xg /i /c /k /e /r /y

해당 디렉터리로 이동합니다.

cd "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86"

INF 파일을 기반으로 CAT 파일(드라이버 패키지 내 모든 파일에 대한 정보 포함)을 생성합니다. Windows Driver Kit(WDK)의 inf2cat.exe 도구를 사용하면 플랫폼에 맞는 CAT 파일을 생성할 수 있습니다.

inf2cat.exe /driver:"C:\DriverCert\xg20" /os:7_X64 /verbose

절차가 올바르게 진행되었는지 확인하려면 대상 디렉터리에 C:\DriverCert\xg\xg20gr.cat 파일이 생성되었는지, 그리고 로그에 다음 메시지들이 있는지 확인합니다.

Signability test complete.
Catalog generation complete.

참고: 경우에 따라 Inf2Cat.exe 명령이 다음과 같은 오류를 반환할 수 있습니다.

Signability test failed.
Errors:
22.9.7: DriverVer set to incorrect date (must be postdated to 4/21/2009 for newest OS) in \hdx861a.inf

이 오류를 수정하려면 .inf 파일의 [Version] 섹션에서 DriverVer = 로 시작하는 줄을 찾아 다음과 같이 변경합니다.

DriverVer=05/01/2009,9.9.9.9

x64 환경에서 Missing AMD64 CatalogFile entry 오류가 발생하거나(32비트의 경우 Missing 32-bit CatalogFile entry), .inf 파일의 [Version] 섹션에 CatalogFile=xg20gr.cat 줄을 추가하면 됩니다.

3. 자체 서명 인증서로 드라이버 패키지 서명하기

다음 폴더로 이동합니다.

cd "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64"

앞서 생성한 인증서를 사용하여 드라이버 패키지(파일 묶음)에 서명합니다. 타임스탬프 서비스로 Verisign을 지정합니다. 다음 명령은 암호로 보호된 .pfx 파일에 저장된 인증서를 사용해 CAT 파일에 디지털 서명을 적용합니다.

signtool sign /f C:\DriverCert\myDrivers.pfx /p P@ss0wrd /t https://timestamp.verisign.com/scripts/timstamp.dll /v C:\DriverCert\xg20\xg20gr.cat

최신 Windows 10 및 Windows 11에서 이 명령을 실행하면 다음과 같은 오류가 발생할 수 있습니다.

SignTool Error: No file digest algorithm specified. Please specify the digest algorithm with the /fd flag. Using /fd SHA256 is recommended and more secure than SHA1. Calling signtool with /fd sha1 is equivalent to the previous behavior. In order to select the hash algorithm used in the signing certificate's signature, use the /fd certHash option.

이 경우 다른 명령을 사용해야 합니다.

signtool sign /tr https://timestamp.digicert.com /td SHA256 /v /f C:\DriverCert\myDrivers.pfx /p P@ss0wrd "C:\DriverCert\xg\xg20gr.cat"

명령 실행 시 SignTool Error: An unexpected internal error has occurred 또는 Error information: SignerTimeStamp() failed. (-2147012865/0x80072eff) 오류가 반환되면, 다른 타임스탬프 서버 URL을 시도해 보세요. 아래 목록 중 하나를 사용할 수 있습니다.

https://timestamp.comodoca.com/authenticode
https://timestamp.globalsign.com/scripts/timstamp.dll
https://timestamp.verisign.com/scripts/timstamp.dll
https://tsa.starfieldtech.com
https://www.startssl.com/timestamp

CAT 파일이 성공적으로 서명되면 다음 메시지가 표시됩니다.

Successfully signed: C:\DriverCert\xg\xg20gr.cat
Number of files successfully Signed: 1

드라이버의 디지털 서명은 .inf 파일에서 참조하는 .cat 파일에 포함됩니다. 다음 명령으로 cat 파일에 담긴 드라이버의 디지털 서명을 확인할 수 있습니다.

SignTool verify /v /pa c:\DriverCert\xg\xg20gr.cat

CAT 파일 속성의 디지털 서명(Digital Signatures) 탭에서도 인증서 정보를 확인할 수 있습니다.

인증서가 신뢰되지 않거나(또는 신뢰할 수 있는 루트 인증서 저장소에 추가되지 않은 경우) SignTool verify 명령 실행 시 다음 오류가 나타납니다.

SignTool Error: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

CAT 파일에는 드라이버 디렉터리에 있는 모든 파일(INF 파일의 CopyFiles 섹션에 나열된 파일들)의 디지털 서명(지문, thumbprint)이 담겨 있습니다. 이 파일 중 하나라도 변경되면 파일 체크섬이 CAT 파일의 데이터와 일치하지 않게 되어, 결과적으로 해당 드라이버의 설치가 실패합니다.

4. Windows에 자체 서명 드라이버 설치하기

서명한 드라이버를 다음 명령으로 다시 설치해 봅니다.

Pnputil –i –a C:\DriverCert\xg20\xg20gr.inf

이제 드라이버의 디지털 서명 누락에 대한 경고가 더 이상 표시되지 않습니다.

Successfully installed the driver on a device on the system.
Driver package added successfully.

Windows 10과 11에서는 다음과 같은 경고가 나타납니다.

Would you like to install this device software?

드라이버 패키지를 설치하려면 설치(Install)를 클릭합니다.

어떤 이유로든 드라이버가 설치되지 않는다면, 상세한 드라이버 설치 로그가 C:\Windows\inf\setupapi.dev.log 파일에 기록되어 있습니다. 이 로그 파일을 통해 드라이버 설치 오류에 대한 더 많은 정보를 얻을 수 있습니다. 대부분의 경우 "Driver package failed signature validation" 오류가 발생하는데, 이는 드라이버의 인증서가 신뢰할 수 있는 인증서 저장소에 추가되지 않았음을 의미하는 경우가 많습니다.

드라이버 설치가 성공하면 setupapi.dev.log 파일에 다음과 같은 내용이 기록됩니다.

>>>  [Device Install (DiInstallDriver) - C:\WINDOWS\System32\DriverStore\FileRepository\xg20gr.inf_amd64_c5955181214aa12b\xg20gr.inf]
>>> Section start 2018/07/22 23:32:57.015
cmd: Pnputil -i -a c:\DriverCert\xg\xg20gr.inf
ndv: Flags: 0x00000000
ndv: INF path: C:\WINDOWS\System32\DriverStore\FileRepository\xg20gr.inf_amd64_c5955181214aa12b\xg20gr.inf
inf: {SetupCopyOEMInf: C:\WINDOWS\System32\DriverStore\FileRepository\xg20gr.inf_amd64_c5955181214aa12b\xg20gr.inf} 13:23:37.046
inf: Copy style: 0x00000000
inf: Driver Store Path: C:\WINDOWS\System32\DriverStore\FileRepository\xg20gr.inf_amd64_c5955181214aa12b\xg20gr.inf
inf: Published Inf Path: C:\WINDOWS\INF\oem23.inf
inf: {SetupCopyOEMInf exit (0x00000000)} 13:23:37.077
<<< Section end 2018/07/22 13:23:37.155
<<< [Exit status: SUCCESS]

5. Windows의 사용자 모드와 커널 모드 드라이버

Windows에서 드라이버는 커널 모드(kernel-mode) 또는 사용자 모드(user mode)로 실행될 수 있다는 점을 기억해 두세요. 이 방식으로 서명한 커널 모드 드라이버는 Secure Boot가 활성화된 UEFI 장치에서 Windows가 부팅될 때 다음 오류와 함께 로드되지 않습니다.

Event ID: 7000
ERROR_DRIVER_BLOCKED
1275 (0x4FB)
This driver has been blocked from loading.

Secure Boot 모드가 활성화되어 있는지는 다음 PowerShell 명령으로 확인할 수 있습니다.

Confirm-SecureBootUEFI

Secure Boot가 활성화된 상태에서 로드되는 모든 커널 모드 드라이버는 Microsoft 인증 프로세스(WHQL – Windows Hardware Quality Lab)를 통해 서명되어야 합니다. 그 이유는 커널이 로드되는 시점에 UEFI가 Windows 로컬 머신 인증서 저장소의 인증서를 검증할 수 없기 때문입니다.

SignTool Error: Signing Cert does not chain to a Microsoft Code Verification Root.

Microsoft는 Windows 10 1607부터 Windows 하드웨어 호환성 프로그램(Windows Hardware Compatibility Program)에 따라 타사 드라이버 인증을 의무화하고 있습니다.

자체 서명된 사용자 모드 드라이버(주로 프린터, 스캐너, 플로터 등)는 Secure Boot가 활성화되어 있어도 정상 작동합니다.
반면 커널 모드 드라이버의 경우, 디지털 서명 검증을 비활성화하고 bcdedit.exe 명령으로 Windows를 테스트 모드로 부팅해야 합니다.

bcdedit.exe /set /nointegritychecks on
bcdedit.exe /set testsigning ON