Computer >> คอมพิวเตอร์ >  >> ระบบ >> Windows Server

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

สคริปต์หรือไฟล์สั่งการที่มีลายเซ็นดิจิทัลทำให้ผู้ใช้สามารถตรวจสอบให้แน่ใจว่าไฟล์นั้นเป็นต้นฉบับและรหัสของไฟล์นั้นไม่ได้ถูกเปลี่ยนแปลงโดยบุคคลที่สาม PowerShell เวอร์ชันปัจจุบันมีเครื่องมือในตัวสำหรับการเซ็นชื่อโค้ดของไฟล์สคริปต์ *.ps1 โดยใช้ใบรับรองดิจิทัล

คุณสามารถลงนามในสคริปต์ PowerShell โดยใช้ใบรับรองประเภทพิเศษ – การลงนามโค้ด . ใบรับรองนี้สามารถรับได้จากหน่วยงานออกใบรับรองทางการค้าภายนอก (AC) องค์กร CA ภายใน หรือคุณสามารถใช้ใบรับรองที่ลงนามเองได้

สมมติว่า บริการ PKI (Active Directory Certificate Services) ถูกทำให้ใช้งานได้ในโดเมนของคุณ มาขอใบรับรองใหม่โดยไปที่ https://CA-server-name/certsrv และขอใบรับรองใหม่ด้วย Code Signing เทมเพลต (ต้องเปิดใช้งานเทมเพลตนี้ก่อนในคอนโซลผู้ออกใบรับรอง)

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

นอกจากนี้ ผู้ใช้สามารถขอใบรับรองสำหรับการเซ็นชื่อสคริปต์ PowerShell จากใบรับรองสแน็ปอิน mmc -> บัญชีของฉัน -> ส่วนบุคคล -> งานทั้งหมด -> ขอใบรับรองใหม่

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

หากคุณขอใบรับรองด้วยตนเอง คุณควรมีไฟล์ใบรับรอง x509 พร้อม .cer การขยาย. ต้องติดตั้งใบรับรองนี้ในที่เก็บใบรับรองในเครื่องคอมพิวเตอร์ของคุณ

คุณสามารถใช้คำสั่ง PowerShell ต่อไปนี้เพื่อเพิ่มใบรับรองไปยังใบรับรองหลักที่เชื่อถือได้ของคอมพิวเตอร์:

$certFile =ส่งออก-Certificate -Cert $cert -FilePath C:\ps\certname.cer
Import-Certificate -CertStoreLocation Cert:\LocalMachine\AuthRoot -FilePath $certFile.FullName

หากคุณต้องการใช้ใบรับรองที่ลงนามเอง ให้ใช้ cmdlet ของ New-SelfSignedCertificate เพื่อสร้างใบรับรอง CodeSigning ด้วยชื่อ DNS testPC1:

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

หลังจากสร้างใบรับรองแล้ว ให้ย้ายจากคอนเทนเนอร์ระดับกลางไปยังรูทที่เชื่อถือได้โดยใช้คอนโซลตัวจัดการใบรับรอง (certmgr.msc )

หลังจากที่คุณได้รับใบรับรองแล้ว คุณสามารถกำหนดค่านโยบายการดำเนินการสคริปต์ของ PowerShell เพื่ออนุญาตให้เรียกใช้สคริปต์ที่ลงนามเท่านั้น ตามค่าเริ่มต้น นโยบายการดำเนินการของ PowerShell บน Windows 10/ Windows Server 2016 ถูกตั้งค่าเป็น จำกัด (บล็อกการดำเนินการของสคริปต์ PowerShell ใดๆ)

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

หากต้องการอนุญาตให้เรียกใช้สคริปต์ PS1 ที่ลงชื่อเท่านั้น คุณสามารถเปลี่ยนนโยบาย PowerShell Eecution เป็น AllSigned หรือ RemoteSigned (มีความแตกต่างเพียงอย่างเดียวที่ RemoteSigned ต้องการลายเซ็นสำหรับสคริปต์ที่ดาวน์โหลดจากอินเทอร์เน็ตเท่านั้น):

Set-ExecutionPolicy AllSigned –Force

ในโหมดนี้ เมื่อเรียกใช้สคริปต์ PowerShell ที่ไม่ได้ลงนาม ข้อผิดพลาดจะปรากฏขึ้น:

File C:\script.ps1 cannot be loaded. The file script.ps1 is not digitally signed. You cannot run this script on the current system.
คุณยังสามารถอนุญาตให้สคริปต์ PowerShell ที่ลงชื่อแล้วทำงานโดยใช้ เปิดการดำเนินการสคริปต์ พารามิเตอร์ Group Policy ภายใต้ Computer Configuration -> Policies -> Administrative Templates -> Windows Components -> Windows PowerShell เปลี่ยนค่าพารามิเตอร์เป็น อนุญาตเฉพาะสคริปต์ที่ลงนาม .

ตอนนี้เรามาดูการเซ็นชื่อไฟล์สคริปต์ PowerShell กัน ก่อนอื่น คุณต้องรับใบรับรอง CodeSign จากที่เก็บใบรับรองในเครื่องของผู้ใช้ปัจจุบัน อันดับแรก มาดูรายการใบรับรองทั้งหมดที่สามารถใช้เซ็นโค้ดได้:

รับ-ChildItem ใบรับรอง:\CurrentUser\my –CodeSigningCert

ในกรณีของเรา เราจะนำใบรับรองแรกจากที่เก็บใบรับรองผู้ใช้ส่วนบุคคลและบันทึกไว้ในตัวแปร $cert:

$cert =(ใบรับรอง Get-ChildItem:\CurrentUser\my –CodeSigningCert)[0]

หากคุณได้ย้ายใบรับรองของคุณไปยังที่เก็บใบรับรองรูทที่เชื่อถือได้ ให้ใช้คำสั่งต่อไปนี้:

$cert =(รับ-ChildItem ใบรับรอง:\LocalMachine\AuthRoot –CodeSigningCert)[0]

จากนั้นคุณสามารถใช้ใบรับรองนี้เพื่อลงนามในไฟล์ PS1 ด้วยสคริปต์ PowerShell ของคุณ:

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

คุณยังสามารถใช้คำสั่งต่อไปนี้ได้ (ในกรณีนี้ เราเลือกใบรับรองที่ลงนามเองที่สร้างไว้ก่อนหน้านี้โดย DnsName):

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

คำแนะนำ . Set-AuthenticodeSignature cmdlet มีพารามิเตอร์ TimestampServer พิเศษที่ระบุ URL สำหรับการประทับเวลาของบริการ หากพารามิเตอร์นี้เว้นว่างไว้ สคริปต์ PS จะหยุดทำงานหลังจากใบรับรองหมดอายุ ตัวอย่างเช่น คุณสามารถตั้งค่าเซิร์ฟเวอร์ประทับเวลาได้ดังนี้:-TimestampServer "https://timestamp.verisign.com/scripts/timstamp.dll"

หากคุณพยายามใช้ใบรับรอง SSL/TLS ทั่วไปเพื่อลงนามในสคริปต์ ข้อผิดพลาดจะปรากฏขึ้น:

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

คุณสามารถเซ็นชื่อไฟล์สคริปต์ PowerShell ทั้งหมดพร้อมกันในโฟลเดอร์:

รับ-ChildItem c:\ps\*.ps1| ชุด-AuthenticodeSignature -Certificate $Cert

ตอนนี้คุณสามารถตรวจสอบได้ว่าไฟล์สคริปต์ PowerShell มีการเซ็นชื่ออย่างถูกต้อง คุณสามารถใช้ Get-AuthenticodeSignature cmdlet หรือเปิดคุณสมบัติไฟล์ PS1 และไปที่ ลายเซ็นดิจิทัล แท็บ

รับ-AuthenticodeSignature c:\ps\test_script.ps1 | ฟุต -AutoSize

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

หาก UnknownError คำเตือนปรากฏขึ้นขณะดำเนินการคำสั่ง Set-AuthenticodeSignature ใบรับรองนี้ไม่น่าเชื่อถือ เนื่องจากอยู่ในที่เก็บใบรับรองส่วนตัวของผู้ใช้

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

คุณต้องย้ายไปยัง Trusted Root Certificates (อย่าลืมตรวจสอบที่เก็บใบรับรอง Windows เป็นระยะเพื่อหาใบรับรองที่น่าสงสัยและอัปเดตรายการใบรับรองหลักที่เชื่อถือได้):

ย้าย-Item -Path $cert.PSPath -Destination "Cert:\LocalMachine\Root"

ตอนนี้เมื่อตรวจสอบลายเซ็นของไฟล์ PS1 แล้ว สถานะที่ถูกต้องจะถูกส่งคืน

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

เมื่อลงนามในไฟล์สคริปต์ PowerShell ชุด Set-AuthenticodeSignature cmdlet จะเพิ่มบล็อกลายเซ็นดิจิทัลที่ส่วนท้ายของไฟล์ข้อความ PS1:

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

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

บล็อกลายเซ็นประกอบด้วยแฮชของสคริปต์ซึ่งเข้ารหัสโดยใช้คีย์ส่วนตัว

ครั้งแรกที่คุณพยายามเรียกใช้สคริปต์ คำเตือนจะปรากฏขึ้น:

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.

หากคุณเลือก [A] เรียกใช้เมื่อเรียกใช้สคริปต์ครั้งแรกเสมอ ครั้งต่อไปที่คุณเรียกใช้สคริปต์ที่ลงนามโดยใช้ใบรับรองนี้ คำเตือนจะไม่ปรากฏอีกต่อไป

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

เพื่อป้องกันไม่ให้คำเตือนนี้ปรากฏขึ้น คุณต้องคัดลอกใบรับรองไปยังผู้เผยแพร่ที่เชื่อถือได้ด้วย ผู้ออกใบรับรอง ใช้การดำเนินการคัดลอก-วางในคอนโซลใบรับรองเพื่อคัดลอกใบรับรองไปยังผู้เผยแพร่ที่เชื่อถือได้ -> ใบรับรอง

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

สคริปต์ PowerShell ที่ลงชื่อแล้วจะทำงานโดยไม่แสดงการแจ้งเตือนของผู้เผยแพร่ที่ไม่น่าเชื่อถือ

เคล็ดลับ . ใบรับรองหลักของ CA และใบรับรองที่ใช้ในการลงนามในสคริปต์จะต้องเชื่อถือได้ (มิฉะนั้น สคริปต์จะไม่ทำงาน) คุณสามารถปรับใช้ใบรับรองจากส่วนกลางไปยังคอมพิวเตอร์โดเมนโดยใช้ GPO ใบรับรองต้องอยู่ในส่วน Public Key ต่อไปนี้ของ GPO:การกำหนดค่าคอมพิวเตอร์ -> นโยบาย -> การตั้งค่า Windows -> การตั้งค่าความปลอดภัย -> นโยบายคีย์สาธารณะ -> ผู้ออกใบรับรองหลักที่เชื่อถือได้ และ ผู้เผยแพร่ที่เชื่อถือได้ .

หากใบรับรองหลักไม่น่าเชื่อถือ เมื่อคุณเรียกใช้สคริปต์ PowerShell ข้อผิดพลาดจะปรากฏขึ้น:

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

จะเกิดอะไรขึ้นหากคุณเปลี่ยนรหัสของไฟล์สคริปต์ PowerShell ที่ลงนามแล้ว ความพยายามในการเรียกใช้จะถูกบล็อกโดยมีการแจ้งเตือนว่าเนื้อหาของสคริปต์มีการเปลี่ยนแปลง

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.

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

ลองตรวจสอบลายเซ็นของสคริปต์โดยใช้ Get-AuthenticodeSignature cmdlet หากแฮชที่คำนวณไม่ตรงกับแฮชในลายเซ็น ข้อความ HashMismatch ปรากฏขึ้น

วิธีการลงนามสคริปต์ PowerShell (PS1) ด้วยใบรับรองการลงนามรหัส

ดังนั้น การแก้ไขโค้ดของสคริปต์ PS1 ที่ลงนามแล้วจะต้องลงนามใหม่