ค้นหาเว็บไซต์

การใช้ Yubikey สำหรับ PowerShell CodeSigning


บทนำ

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

ยูบิกี้มาช่วยแล้ว

Yubikey คืออุปกรณ์ USB ขนาดเล็กที่มีลักษณะคล้ายกับแท่ง USB ที่บางมาก ฉันใช้ Yubikey เป็นปัจจัยที่สองมาระยะหนึ่งแล้วและมันก็ใช้งานได้ดี แต่ฉันไม่ได้คิดถึงความเป็นไปได้ที่จะใช้มันในการเซ็นโค้ด เมื่อตั้งค่าด้วยใบรับรอง มันจะทำงานเหมือนกับสมาร์ทการ์ด เพียงเสียบปลั๊กแล้วมันจะเก็บคีย์ส่วนตัวไว้ให้คุณ เมื่อไม่นานมานี้ ฉันได้รีเซ็ตคีย์แล้ว ให้รหัส PIN ใหม่และเก็บใบรับรองการลงนามของฉันไว้ ตอนนี้ฉันสามารถเสียบเข้ากับคอมพิวเตอร์เครื่องใดก็ได้และมีใบรับรองของฉันพร้อมใช้โดยไม่ต้องกังวลเรื่องการเก็บคีย์ส่วนตัวของฉันไว้ที่ใดที่หนึ่ง สำหรับคำแนะนำเกี่ยวกับวิธีตั้งค่า Yubikey โปรดอ่านโพสต์ของฉันเกี่ยวกับวิธีตั้งค่า Yubikey สำหรับการลงนามโค้ด PowerShell

ลงนามรหัสกับ Yubikey ของฉัน

เมื่อใบรับรองของฉันถูกนำเข้าไปยัง Yubikey ของฉันแล้ว ฉันสามารถใส่รหัสลงในคอมพิวเตอร์เครื่องใดก็ได้ และใบรับรองจะพร้อมใช้งานในที่เก็บใบรับรองของผู้ใช้ปัจจุบัน มาแจกแจงร้านค้าและดูว่ามีลักษณะอย่างไร:

Get-ChildItem -Path "cert:\currentuser\my" -CodeSigning

การใช้พารามิเตอร์ -CodeSigning ใช้งานได้เฉพาะเมื่อเส้นทางชี้ไปยังที่เก็บใบรับรอง และจะทำให้ Get-ChildItem ส่งคืนใบรับรองที่ถูกต้องสำหรับการลงนามโค้ดเท่านั้น

ต่อไปเรามาเซ็นอะไรบางอย่างกันเถอะ!

ฉันมีโมดูลชื่อ DSACL ซึ่งมีฟังก์ชันสำหรับการตั้งค่า ACL ใน Active Directory ฉันต้องการลงนามในโมดูลนี้ก่อนที่จะโพสต์ลงในแกลเลอรี มีสองวิธีในการลงนามโมดูล การลงนามแต่ละไฟล์ และการใช้การลงนามแค็ตตาล็อก ฉันจะใช้ทั้งสองอย่าง คุณสามารถอ่านเพิ่มเติมได้ในคู่มือแนวทางปฏิบัติที่ดีที่สุดในการเผยแพร่สำหรับแกลเลอรี PowerShell

ก่อนอื่น ฉันต้องอ้างอิงถึงใบรับรองของฉัน หากคุณมีใบรับรองการเซ็นชื่อรหัสเดียวบนคอมพิวเตอร์ของคุณ คุณสามารถจัดเก็บเอาต์พุตจาก Get-ChildItem ด้านบนลงในตัวแปรได้ หากคุณมีมากกว่าหนึ่งอัน ฉันชอบใช้ Out-GridView เพื่อเลือกอันที่ฉันต้องการ เช่นนี้:

$Cert = Get-ChildItem -Path 'cert:\currentuser\my' -CodeSigning | Out-GridView -PassThru

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

Get-ChildItem -Path '*.ps*' | Set-AuthenticodeSignature -Certificate $Cert -TimestampServer 'http://timestamp.digicert.com'

ส่วนถัดไปคือการสร้างไฟล์แค็ตตาล็อกซึ่งจะมีผลรวมแฮชของแต่ละไฟล์ เพื่อเป็นการยืนยันว่าไม่มีการเปลี่ยนแปลงใดๆ สิ่งนี้ถูกใช้โดย PowerShellGet เมื่อฉันติดตั้งโมดูลโดยใช้ Install-Module ฉันสามารถเลือกได้ระหว่างการใช้แคตตาล็อกเวอร์ชัน 1 หรือเวอร์ชัน 2 เวอร์ชัน 1 จะใช้ SHA1 และเวอร์ชัน 2 จะใช้อัลกอริทึม SHA256 เพื่อความเข้ากันได้กับ Windows 7 (ซึ่งเราอาจจะต้องใช้งานต่อไปอีกสักระยะหนึ่ง) ฉันจะใช้เวอร์ชัน 1 คำสั่งที่ฉันใช้คือ:

New-FileCatalog -CatalogVersion 1 -CatalogFilePath .\DSACL.cat -Path $PWD.Path

ที่นี่ฉันยังอยู่ในไดเร็กทอรีที่ไฟล์ของฉันที่จะลงนามอยู่ สิ่งนี้ทำให้ฉันสามารถใช้ตัวแปรเริ่มต้น $PWD ซึ่งมีเส้นทางของโฟลเดอร์ปัจจุบัน สิ่งนี้จะสร้างไฟล์ DSACL.cat ซึ่งจะมีแฮชสำหรับแต่ละไฟล์ในไดเร็กทอรี หากไฟล์ใดๆ มีการเปลี่ยนแปลง เพิ่ม หรือลบ ไฟล์ DSACL.cat จะใช้งานไม่ได้อีกต่อไป ตอนนี้เพื่อให้แน่ใจว่าไฟล์แค็ตตาล็อกของฉันไม่เปลี่ยนแปลง ฉันจะเซ็นชื่อโดยใช้คำสั่งต่อไปนี้:

Set-AuthenticodeSignature -Certificate $Cert -TimestampServer 'http://timestamp.digicert.com' -FilePath .\DSACL.cat

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

และนั่นมัน! ลงนามอย่างมีความสุข!

บทความที่เกี่ยวข้อง