Computer >> Máy Tính >  >> Hệ thống >> máy chủ Windows

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Tập lệnh hoặc tệp thực thi có chữ ký số cho phép người dùng đảm bảo rằng tệp là nguyên bản và mã của tệp đó không bị thay đổi bởi bên thứ ba. Các phiên bản hiện tại của PowerShell có các công cụ tích hợp để ký mã các tệp tập lệnh * .ps1 bằng chứng chỉ kỹ thuật số.

Bạn có thể ký tập lệnh PowerShell bằng loại chứng chỉ đặc biệt - Ký mã . Chứng chỉ này có thể được lấy từ tổ chức chứng nhận thương mại bên ngoài (AC), CA doanh nghiệp nội bộ hoặc bạn có thể sử dụng chứng chỉ tự ký.

Giả sử, các dịch vụ PKI (Dịch vụ Chứng chỉ Active Directory) được triển khai trong miền của bạn. Hãy yêu cầu chứng chỉ mới bằng cách truy cập https:// CA-server-name / certsrv và yêu cầu chứng chỉ mới với Mã ký mẫu (mẫu này trước tiên phải được bật trong bảng điều khiển của Tổ chức phát hành chứng chỉ).

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Ngoài ra, người dùng có thể yêu cầu chứng chỉ để ký các tập lệnh PowerShell từ Chứng chỉ đính kèm mmc -> Tài khoản của tôi -> Cá nhân -> Tất cả Công việc -> Yêu cầu chứng chỉ mới.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Nếu bạn đã yêu cầu chứng chỉ theo cách thủ công, bạn phải có tệp chứng chỉ x509 với .cer gia hạn. Chứng chỉ này phải được cài đặt trong kho lưu trữ chứng chỉ cục bộ trên máy tính của bạn.

Bạn có thể sử dụng các lệnh PowerShell sau để thêm chứng chỉ vào chứng chỉ gốc đáng tin cậy của máy tính:

$certFile = Export-Certificate -Cert $cert -FilePath C:\ps\certname.cer
Import-Certificate -CertStoreLocation Cert:\LocalMachine\AuthRoot -FilePath $certFile.FullName

Nếu bạn muốn sử dụng chứng chỉ tự ký, hãy sử dụng lệnh ghép ngắn New-SelfSignedCertificate để tạo chứng chỉ CodeSign với tên DNS testPC1:

New-SelfSignedCertificate -DnsName testPC1 -Type CodeSigning
$cert = New-SelfSignedCertificate -Subject "Cert for Code Signing” -Type CodeSigningCert -DnsName test1 -CertStoreLocation cert:\LocalMachine\My

Sau khi chứng chỉ đã được tạo, hãy di chuyển nó từ vùng chứa Trung gian sang Gốc tin cậy bằng bảng điều khiển Trình quản lý chứng chỉ (certmgr.msc ).

Sau khi nhận được chứng chỉ, bạn có thể định cấu hình Chính sách thực thi tập lệnh PowerShell để chỉ cho phép chạy các tập lệnh đã ký. Theo mặc định, Chính sách thực thi PowerShell trên Windows 10 / Windows Server 2016 được đặt thành Bị hạn chế (chặn thực thi bất kỳ tập lệnh PowerShell nào).

File C:\ps\script.ps1 cannot be loaded because running scripts is disabled on this system.

Để chỉ cho phép các tập lệnh PS1 đã ký chạy, bạn có thể thay đổi Chính sách thực thi PowerShell thành Đã ký hoặc Đã ký từ xa (với điểm khác biệt duy nhất là RemoteSigned chỉ yêu cầu chữ ký đối với các tập lệnh được tải xuống từ Internet):

Set-ExecutionPolicy AllSigned –Force

Trong chế độ này, khi chạy các tập lệnh PowerShell chưa được đánh dấu, lỗi sẽ xuất hiện:

File C:\script.ps1 cannot be loaded. The file script.ps1 is not digitally signed. You cannot run this script on the current system.
Bạn cũng có thể cho phép các tập lệnh PowerShell đã ký chạy bằng cách sử dụng Bật thực thi tập lệnh Tham số chính sách nhóm trong Cấu hình máy tính -> Chính sách -> Mẫu quản trị -> Thành phần Windows -> Windows PowerShell. Thay đổi giá trị tham số thành Chỉ cho phép các tập lệnh đã ký .

Bây giờ, hãy chuyển sang ký tệp tập lệnh PowerShell. Trước hết, bạn cần lấy chứng chỉ CodeSign từ kho chứng chỉ cục bộ của người dùng hiện tại. Trước tiên, hãy liệt kê tất cả các chứng chỉ có thể được sử dụng để ký mã:

Get-ChildItem cert:\CurrentUser\my –CodeSigningCert

Trong trường hợp của chúng tôi, chúng tôi sẽ lấy chứng chỉ đầu tiên từ cửa hàng cert của người dùng cá nhân và lưu nó trong biến $ cert:

$cert = (Get-ChildItem cert:\CurrentUser\my –CodeSigningCert)[0]

Nếu bạn đã chuyển chứng chỉ của mình sang kho lưu trữ chứng chỉ gốc đáng tin cậy, hãy sử dụng lệnh sau:

$cert = (Get-ChildItem Cert:\LocalMachine\AuthRoot –CodeSigningCert)[0]

Sau đó, bạn có thể sử dụng chứng chỉ này để ký tệp PS1 bằng tập lệnh PowerShell của mình:

Set-AuthenticodeSignature -Certificate $cert -FilePath C:\PS\testscript.ps1

Bạn cũng có thể sử dụng lệnh sau (trong trường hợp này, chúng tôi chọn chứng chỉ tự ký do DnsName tạo trước đó):

Set-AuthenticodeSignature C:\PS\test_script.ps1 @(gci Cert:\LocalMachine\AuthRoot -DnsName testPC1 -codesigning)[0]

Gợi ý . Lệnh ghép ngắn Set-AuthenticodeSignature có tham số TimestampServer đặc biệt chỉ định URL cho Dấu thời gian của dịch vụ. Nếu tham số này bị bỏ trống, tập lệnh PS sẽ ngừng chạy sau khi chứng chỉ hết hạn. Ví dụ:bạn có thể đặt máy chủ dấu thời gian như sau:-TimestampServer "https://timestamp.verisign.com/scripts/timstamp.dll"

Nếu bạn cố gắng sử dụng chứng chỉ SSL / TLS phổ biến để ký tập lệnh, lỗi sẽ xuất hiện:

Set-AuthenticodeSignature: Cannot sign code. The specified certificate is not suitable for code signing.

Bạn có thể ký tất cả các tệp tập lệnh PowerShell cùng một lúc trong thư mục:

Get-ChildItem c:\ps\*.ps1| Set-AuthenticodeSignature -Certificate $Cert

Bây giờ bạn có thể kiểm tra xem tệp tập lệnh PowerShell đã được ký đúng chưa. Bạn có thể sử dụng lệnh ghép ngắn Get-AuthenticodeSignature hoặc mở thuộc tính tệp PS1 và đi tới Chữ ký kỹ thuật số tab.

Get-AuthenticodeSignature c:\ps\test_script.ps1 | ft -AutoSize

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Nếu một UnknownError cảnh báo xuất hiện trong khi thực hiện lệnh Set-AuthenticodeSignature thì chứng chỉ này không đáng tin cậy vì nằm trong kho lưu trữ chứng chỉ cá nhân của người dùng.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Bạn cần chuyển nó sang Chứng chỉ gốc đáng tin cậy (đừng quên kiểm tra định kỳ kho chứng chỉ Windows để tìm chứng chỉ đáng ngờ và cập nhật danh sách chứng chỉ gốc đáng tin cậy):

Move-Item -Path $cert.PSPath -Destination "Cert:\LocalMachine\Root"

Bây giờ khi xác minh chữ ký của tệp PS1, trạng thái Hợp lệ sẽ được trả về.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Khi ký tệp kịch bản PowerShell, lệnh ghép ngắn Set-AuthenticodeSignature sẽ thêm khối chữ ký số vào cuối tệp văn bản PS1:

# SIG # Begin signature block
...........
...........
# SIG # End signature block

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Khối chữ ký chứa hàm băm của tập lệnh, được mã hóa bằng khóa riêng tư.

Lần đầu tiên bạn cố gắng chạy tập lệnh, một cảnh báo sẽ xuất hiện:

Do you want to run software from this untrusted publisher?
File C:\PS\script.ps1 is published by CN=testPC1 and is not trusted on your system. Only run scripts from trusted publishers.

Nếu bạn chọn [A] Luôn chạy ở lần chạy tập lệnh đầu tiên , vào lần tiếp theo bạn chạy tập lệnh, được ký bằng chứng chỉ này, cảnh báo sẽ không còn xuất hiện nữa.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Để ngăn cảnh báo này xuất hiện, bạn cũng cần sao chép chứng chỉ vào Nhà xuất bản đáng tin cậy cơ quan cấp chứng chỉ. Sử dụng thao tác Sao chép-Dán trong bảng điều khiển Chứng chỉ để sao chép chứng chỉ vào Nhà xuất bản đáng tin cậy -> Chứng chỉ.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Tập lệnh PowerShell đã ký bây giờ sẽ chạy mà không hiển thị thông báo nhà xuất bản không đáng tin cậy.

Mẹo . Chứng chỉ gốc của CA và chứng chỉ được sử dụng để ký tập lệnh phải đáng tin cậy (nếu không, tập lệnh sẽ không chạy). Bạn có thể triển khai tập trung chứng chỉ cho các máy tính miền bằng GPO. Các chứng chỉ cần được đặt trong các phần Khóa công khai sau của GPO:Cấu hình máy tính -> Chính sách -> Cài đặt Windows -> Cài đặt bảo mật -> Chính sách khóa công khai -> Tổ chức phát hành chứng chỉ gốc đáng tin cậy Nhà xuất bản đáng tin cậy .

Nếu chứng chỉ gốc không đáng tin cậy, thì khi bạn chạy tập lệnh PowerShell, lỗi sẽ xuất hiện:

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

Điều gì sẽ xảy ra nếu bạn thay đổi mã của tệp tập lệnh PowerShell đã ký? Nỗ lực chạy nó sẽ bị chặn với thông báo rằng nội dung của tập lệnh đã được thay đổi.

File xx.ps1 cannot be loaded. The contents of file xx.ps1 might  have been changed by an unauthorized user or process, because the hash of the file does not match the hash stored in the digital signature. The script cannot run on the specified system.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Cố gắng xác minh chữ ký của tập lệnh bằng lệnh ghép ngắn Get-AuthenticodeSignature. Nếu hàm băm được tính toán không khớp với hàm băm trong chữ ký, thông báo HashMismatch xuất hiện.

Làm thế nào để ký một Tập lệnh PowerShell (PS1) với một chứng chỉ ký mã?

Do đó, bất kỳ sửa đổi nào đối với mã của tập lệnh PS1 đã ký sẽ yêu cầu ký lại.