Powershell 腳本數(shù)字簽名實(shí)現(xiàn)方法
腳本很容易被冒名頂替或者更改,因?yàn)樗鼈兪怯杉兾谋緲?gòu)成的。數(shù)字簽名為腳本提供了更高的安全性,因?yàn)樗艽_定腳本和腳本的編輯者的唯一性,并且不能被更改。作為腳本的發(fā)布者,你能確定你的腳本沒有被惡意篡改。即使專家也無能為力,因?yàn)檫@種機(jī)制是基于復(fù)雜邏輯的。幸運(yùn)的是,在實(shí)際應(yīng)用中,你不需要深究這些細(xì)節(jié),只需要掌握Powershell腳本簽名的機(jī)制和過程。
準(zhǔn)備一個(gè)合適的證書
因?yàn)椴荒苁褂脗鹘y(tǒng)的紙質(zhì)簽名給Powershell腳本進(jìn)行簽名,你需要另一個(gè)工具“證書”。證書就像一把私有并且安全的鑰匙。證書是你的個(gè)人電子身份特征。這把私密的鑰匙確保只有證書的擁有者使用證書進(jìn)行腳本簽名。
可以通過mmc添加管理單元查看證書,但是在Powershell中有專門查看證書的支持??梢酝ㄟ^虛擬驅(qū)動(dòng)器cert:查看本機(jī)支持的證書。
創(chuàng)建自簽名證書
創(chuàng)建一個(gè)自簽名證書,需要用到microsoft的工具,makecert.exe 。這個(gè)工具不能單獨(dú)下載,但是它包含在微軟的.NET framework中,如果你的電腦上已經(jīng)安裝了Visual studio 那就方便多了。
開始->所有程序-Microsoft Visual Studio 2010->Visual Studio Tools->Visual Studio 命令提示(2010)
makecert.exe -pe -r -n "cn=MosserPowerShellTestCert" -eku 1.3.6.1.5.5.7.3.3 -ss "my" Succeeded
這里要稍微注意 -eku 參數(shù):1.3.6.1.5.5.7.3.3,不能是其它,否則證書的預(yù)期目的屬性就不是代碼簽名了。
上面創(chuàng)建的證書會(huì)自動(dòng)保存在CurrentUserMy 路徑下面??梢栽赑owershell中查看:
PS E:> ls cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"} 目錄: Microsoft.PowerShell.SecurityCertificate::CurrentUserMy Thumbprint Subject ---------- ------- BA61AF0B8A856422AD9EF86104C8CEDB2583A21A CN=MosserPowerShellTestCert
驗(yàn)證代碼簽名證書
查看支持代碼簽名的證書
查看證書的簽發(fā)者,代表,序列號(hào),指紋。
## 查看預(yù)期目的為代碼簽名的證書: $certs = @(Dir cert:CurrentUserMy -codeSigningCert) "找到 {0} 個(gè)代碼簽名證書" -f $certs.count # 找到 1 個(gè)代碼簽名證書 ## 選擇 剛才創(chuàng)建的證書 $certificate=ls cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"} ## 證書的代表 $certificate.subject # CN=MosserPowerShellTestCert ## 證書的簽發(fā)者 $certificate.issuer # CN=MosserPowerShellTestCert ## 證書的序列號(hào),指紋 $certificate | select SerialNumber,Thumbprint | fl * # SerialNumber : C23F35EA85D9A5AB466C07A7C0469A78 # Thumbprint : 586A4332F0528867DA6A0900FCF0938EDD277E22
聲明一個(gè)證書受信任
你會(huì)發(fā)現(xiàn),在你指定證書的類型,頒發(fā)者的名稱等信息后,證書的原始數(shù)據(jù)(RawData)會(huì)自動(dòng)生成。這樣你不能假冒別人生成一個(gè)證書,別人也不能假冒你的名字生成一個(gè)證書。如果通過Powershell查看之前生成的證書是否受信任,答案為否。
PS E:> $certificate.Verify() False
為什么我們剛才生成的證書不受信任呢?我們可以通過一個(gè)簡(jiǎn)單的步驟找到答案。在.NET 中有一個(gè)方法:DisplayCertificate()可以通過對(duì)話框顯示證書,位于System.Security.dll中。這個(gè)dll默認(rèn)沒有引用,需要添加引用,之后顯示證書對(duì)話框。
PS E:> [System.Reflection.Assembly]::LoadWithPartialName("System.Security") GAC Version Location --- ------- -------- True v2.0.50727 C:windowsassemblyGAC_MSILSystem.Security2.0.0.0__b03f5f7f11d50a3aSys... [System.Security.Cryptography.x509Certificates.X509Certificate2UI]::DisplayCertificate($certificate)
Powershell 查看證書 不受信任
對(duì)話框提示:此CA根證書不受信任,要啟用信任,請(qǐng)將該證書安裝到”受信任的根證書頒發(fā)機(jī)構(gòu)“存儲(chǔ)區(qū)。
所以接下來可以將該證書復(fù)制到受信任的存儲(chǔ)區(qū)??梢酝ㄟ^certmgr.msc 手動(dòng)操作,也可以通過Powershell自動(dòng)化操作。
PS E:> $rootStore= New-Object system.security.cryptography.X509Certificates.x509Store("root","Curre ntuser") $rootStore.Open("ReadWrite") $rootStore.Add($certificate) $rootStore.Close()
在執(zhí)行Add操作時(shí),會(huì)有一個(gè)確認(rèn)的對(duì)話框,確定即可。
接下來我們查看一下驗(yàn)證信息。
PS E:> $certificate.Verify() True
給Powershell 腳本簽名
給Powershell腳本進(jìn)行數(shù)字簽名只需要兩步:找的一個(gè)受信任的代碼簽名證書,剩下的工作請(qǐng)交給:Set-AuthenticodeSignature吧。
PS E:> 'Write-Host "我的第一個(gè)簽名腳本"' > firstSignScript.ps1 PS E:> $certificate=ls cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"} PS E:> Set-AuthenticodeSignature .firstSignScript.ps1 $certificate 目錄: E: SignerCertificate Status Path ----------------- ------ ---- 586A4332F0528867DA6A0900FCF0938EDD277E22 Valid firstSignScript.ps1 PS E:> Get-Content .firstSignScript.ps1 Write-Host "我的第一個(gè)簽名腳本" # SIG # Begin signature block # MIIEIQYJKoZIhvcNAQcCoIIEEjCCBA4CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUnxRdr+yE6sFotfvZjfn8k15W # OtigggI0MIICMDCCAZ2gAwIBAgIQwj816oXZpatGbAenwEaaeDAJBgUrDgMCHQUA # MCMxITAfBgNVBAMTGE1vc3NlclBvd2VyU2hlbGxUZXN0Q2VydDAeFw0xMjA2MTYx # MzAyMjZaFw0zOTEyMzEyMzU5NTlaMCMxITAfBgNVBAMTGE1vc3NlclBvd2VyU2hl # bGxUZXN0Q2VydDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr/2eZ6iS3Zi4 # Q2RsXFPRmDynztxPwArZ6SK663R6X2Dfqwv+kuev4VbEHJ20Bvd9yLvCS4QgCCR6 # n0D+ELfBy6aRpst51dNKNGV74TZIBu1M5EKG2+didLrKTx3lwEC66Bl+QyFiOzcH # ZhQcaZzgdx8m8EN10/B2cDg9Tm9ppQsCAwEAAaNtMGswEwYDVR0lBAwwCgYIKwYB # BQUHAwMwVAYDVR0BBE0wS4AQjHzaaSg4KlNdyvIpJNjeiqElMCMxITAfBgNVBAMT # GE1vc3NlclBvd2VyU2hlbGxUZXN0Q2VydIIQwj816oXZpatGbAenwEaaeDAJBgUr # DgMCHQUAA4GBAFA3lvWcbA8mWndKdIOCzQUbC9/+1vIeQRGaH7L6U6OHZuV2IBw1 # EpLxz1/dyFEMNZmy9z+/YjfJi774UY1eTzOJnz0AYKGPpM0BK2ieGZzPDIlbkpv1 # ywrv5BtRt053MNHRYaZQP0v9Sp6pOB4h10tKnvh0DW882zRPeB4hkK+fMYIBVzCC # AVMCAQEwNzAjMSEwHwYDVQQDExhNb3NzZXJQb3dlclNoZWxsVGVzdENlcnQCEMI/ # NeqF2aWrRmwHp8BGmngwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKA # AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFMgyEZ64UFors3z9JGuKLVxh # P2hLMA0GCSqGSIb3DQEBAQUABIGAMHFJHMVlauxKGIo2p9ieFBVp4Am6n533k89j # 7pQXKOGmU/sG9d8PILifHLJZw7BU66+uZFvOSXlUxvqaPRAdeosc2BLDPf5Cu6o7 # 61BfSJc2H5dQCgbK/90OKmeJp4KJQRCk7HLEBvV23ddVSyl4CPplbUcTVmo92Zd1 # B/Moxro= # SIG # End signature block
遞歸給所有腳本文件簽名
給當(dāng)前文件下的所有腳本簽名
PS E:> Set-AuthenticodeSignature (ls *.ps1) $certificate 目錄: E: SignerCertificate Status Path ----------------- ------ ---- 586A4332F0528867DA6A0900FCF0938EDD277E22 Valid firstSignScript.ps1 586A4332F0528867DA6A0900FCF0938EDD277E22 Valid MyScript.ps1 586A4332F0528867DA6A0900FCF0938EDD277E22 Valid pipeline.ps1 586A4332F0528867DA6A0900FCF0938EDD277E22 Valid PSLib.ps1
如果你喜歡你甚至可以遞歸使用
Set-AuthenticodeSignature (Dir -recurse -include *.ps1) $certificate
使用對(duì)話框選擇證書
如果機(jī)器上安裝了代碼簽名的證書有許多,你可以通過friendName 或者證書的名稱,證書的指紋,過濾一個(gè)證書供腳本簽名。
Dir cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"}
另一種方法是通過.NET中的內(nèi)置的對(duì)話框進(jìn)行選擇。將查詢到的證書傳遞給SelectFromCollection()方法,在在作此操作之前必須將證書放在一個(gè)特殊的集合中。
# 對(duì)話框文本: $title = "可用的證書" $text = "請(qǐng)選擇用于代碼簽名的證書:" # Find certificates: $certificates = Dir cert: -recurse -codeSigningCert # 加載 System.Security 類庫(kù) # 將證書存放在特殊的集合(X509Certificate2Collection)中: [Reflection.Assembly]::LoadWithPartialName("System.Security") $collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection $certificates | ForEach-Object { $collection.Add($_) } # 顯示選項(xiàng): $certificate =[System.Security.Cryptography.x509Certificates.X509Certificate2UI]::` SelectFromCollection($collection, $title, $text, 0) # 使用選擇的證書進(jìn)行數(shù)字簽名 Set-AuthenticodeSignature -Certificate $certificate[0] -FilePath .firstSignScript.ps1
Powershel l對(duì)話框選擇 證書
Powershell腳本簽名驗(yàn)證
在腳本中簽名到底能帶來什么好處,那就是可以進(jìn)行驗(yàn)證??梢允謩?dòng)驗(yàn)證,也可以自動(dòng)驗(yàn)證。簽名驗(yàn)證會(huì)告訴你腳本是否信任,或者是否包含了惡意篡改。
用戶自行驗(yàn)證:手動(dòng)驗(yàn)證,可以檢查一個(gè)腳本是否包含簽名代碼,簽名者是誰?該簽名者是否受信任。
自動(dòng)驗(yàn)證:如果你將Powershell的腳本執(zhí)行策略設(shè)置為AllSigned. Powershell會(huì)在你嘗試運(yùn)行腳本時(shí)自動(dòng)驗(yàn)證,代碼和腳本簽名是否一致。并且會(huì)詢問簽名者是否受信任。
手動(dòng)驗(yàn)證
Get-AuthenticodeSignature命令可以驗(yàn)證簽名。例如創(chuàng)建一個(gè)腳本,不進(jìn)行簽名,通過該命令進(jìn)行驗(yàn)證。屬性StatusMessage會(huì)告訴你簽名驗(yàn)證的結(jié)果。
"'未簽名'" >notsign.ps1 $checkResult=Get-AuthenticodeSignature .notsign.ps1 $checkResult.Status NotSigned $checkResult.StatusMessage 文件 E:notsign.ps1 未經(jīng)數(shù)字簽名。系統(tǒng)將不執(zhí)行該腳本。有關(guān)詳細(xì)信息,請(qǐng)參閱 "get-help about_signing" 。 $checkResult.Status.GetType().fullName System.Management.Automation.SignatureStatus
如果運(yùn)行該未簽名的腳本,也會(huì)收到錯(cuò)誤提示信息,也就是StatusMessage中包含的信息。腳本的驗(yàn)證結(jié)果狀態(tài)包括:
成員名稱 | 描述 |
HashMismatch | 文件的哈希碼和存儲(chǔ)的簽名不匹配 |
Incompatible | 無法驗(yàn)證簽名,因?yàn)榕c當(dāng)前操作系統(tǒng)不兼容 |
NotSigned | 文件沒有簽名 |
NotSupportedFileFormat | 指定的文件格式不支持的系統(tǒng)簽名。這通常意味著系統(tǒng)不知道如何簽名或驗(yàn)證文件的類型。 |
NotTrusted | 證書的發(fā)布者在系統(tǒng)中不受信任. |
UnknownError | 文件簽名無效 |
Valid | 該文件有一個(gè)有效的簽名。這意味著只有簽名的語法上是合法的。這并不意味著信任。 |
自動(dòng)驗(yàn)證
你不須要去驗(yàn)證腳本的簽名,當(dāng)你運(yùn)行一個(gè)腳本時(shí),Powershell會(huì)自動(dòng)驗(yàn)證。即使驗(yàn)證過的腳本,如果有部分內(nèi)容更新,自動(dòng)驗(yàn)證也會(huì)給出警告。
在用戶將腳本執(zhí)行策略設(shè)置為AllSigned和RemoteSigned時(shí),自動(dòng)驗(yàn)證就會(huì)激活,如果將執(zhí)行策略設(shè)置為AllSigned,所有的腳本都會(huì)驗(yàn)證。如果你選擇RemoteSigned,從網(wǎng)絡(luò)上下載的腳本執(zhí)行會(huì)提示需要簽名。
# 設(shè)置 ExecutionPolicy 為 AllSigned. 所有 # 腳本必須有正確的簽名: Set-ExecutionPolicy AllSigned # 創(chuàng)建一個(gè)沒有簽名的腳本. # 該腳本不會(huì)執(zhí)行: 無法加載文件 E:unSigned.ps1。文件 E:unSigned.ps1 未經(jīng)數(shù)字簽名。系統(tǒng)將不執(zhí)行該腳本。有關(guān)詳細(xì)信息, 請(qǐng)參閱 "get-help about_signing"。。 所在位置 行:1 字符: 15 + .unSigned.ps1 < <<< + CategoryInfo : NotSpecified: (:) [], PSSecurityException + FullyQualifiedErrorId : RuntimeException 即使簽名可以通過驗(yàn)證,也需要用戶的批準(zhǔn),才能執(zhí)行。 .firstSignScript.ps1 是否要運(yùn)行來自此不可信發(fā)布者的軟件? 文件 E:firstSignScript.ps1 由 CN=MosserPowerShellTestCert 發(fā)布,該文件對(duì)于您的系統(tǒng)是不可信的。請(qǐng)只運(yùn)行來自可信發(fā)布者的腳本。 [V] 從不運(yùn)行(V) [D] 不運(yùn)行(D) [R] 運(yùn)行一次(R) [A] 始終運(yùn)行(A) [?] 幫助 (默認(rèn)值為“D”): a 我的第一個(gè)簽名腳本 #第二次執(zhí)行,不會(huì)詢問 我的第一個(gè)簽名腳本
Windows PowerShell顯示執(zhí)行的腳本未進(jìn)行數(shù)字簽名。
設(shè)置一下可以運(yùn)行未簽名的腳本或者為你的腳本簽名。
set-executionpolicy Bypass
到這里文章就結(jié)束了,需要的朋友可以參考一下。
相關(guān)文章
PowerShell入門教程之Cmd命令與PowerShell命令相互調(diào)用的方法
這篇文章主要介紹了PowerShell入門教程之Cmd命令與PowerShell命令相互調(diào)用的方法,本文講解了在Cmd命令中調(diào)用PowerShell命令、在PowerShell命令中調(diào)用Cmd命令的方法,需要的朋友可以參考下2014-10-10Powershell腳本中使用條件斷點(diǎn)實(shí)例
這篇文章主要介紹了Powershell腳本中使用條件斷點(diǎn)實(shí)例,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-03-03PowerShell入門教程之訪問.Net程序集、COM和WMI實(shí)例
這篇文章主要介紹了PowerShell入門教程之訪問.Net程序集、COM和WMI實(shí)例,本文講解了PowerShell作為Windows平臺(tái)的脫水語言來訪問其它資源的例子,需要的朋友可以參考下2014-10-10PowerShell多線程執(zhí)行前后臺(tái)作業(yè)的例子
使用后臺(tái)作業(yè)執(zhí)行多個(gè)任務(wù)從先前的技巧中看不是非常高效,它在處理每個(gè)后臺(tái)作業(yè)返回結(jié)果時(shí)將會(huì)浪費(fèi)很多性能。一個(gè)更有效的方法是使用進(jìn)程內(nèi)的任務(wù)。他能分別單獨(dú)的執(zhí)行任務(wù)與Powershell類似,所以它不是按順序返回值的2014-04-04PowerShell Out-File向只讀文件寫入內(nèi)容的方法
這篇文章主要介紹了PowerShell Out-File向只讀文件寫入內(nèi)容的方法,只需要加一個(gè)-Force參數(shù)即可,需要的朋友可以參考下2014-08-08PowerShell中使用Out-File把字符串或運(yùn)行結(jié)果保存到文件的方法
這篇文章主要介紹了PowerShell中使用Out-File把字符串或運(yùn)行結(jié)果保存到文件的方法,重點(diǎn)在于Out-File命令的使用方法上,需要的朋友可以參考下2014-08-08powershell遠(yuǎn)程管理服務(wù)器磁盤空間的實(shí)現(xiàn)代碼
這篇文章主要介紹了powershell遠(yuǎn)程管理服務(wù)器磁盤空間的實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-11-11PowerShell中執(zhí)行Javascript的方法示例
這篇文章主要介紹了PowerShell中執(zhí)行Javascript的方法示例,特殊場(chǎng)景下可能會(huì)用到這個(gè)技巧,需要的朋友可以參考下2014-07-07