设为首页 收藏本站
查看: 1309|回复: 0

Powershell 脚本数字签名

[复制链接]

尚未签到

发表于 2018-9-2 14:09:07 | 显示全部楼层 |阅读模式
Powershell 脚本数字签名 1
  此文章于2012年6月17日发表在 Powershell 并加以 Powershell教程  签名 的标签 by Mooser Lee.
  本文索引
  [隐藏]

  •   1准备一个合适的证书
  •   2创建自签名证书
  •   3验证代码签名证书
  •   4声明一个证书受信任
  •   5给Powershell 脚本签名
  •   6递归给所有脚本文件签名
  •   7使用对话框选择证书
  •   8Powershell脚本签名验证

    •   8.1手动验证
    •   8.2自动验证

  脚本很容易被冒名顶替或者更改,因为它们是由纯文本构成的。数字签名为脚本提供了更高的安全性,因为它能确定脚本和脚本的编辑者的唯一性,并且不能
被更改。作为脚本的发布者,你能确定你的脚本没有被恶意篡改。即使专家也无能为力,因为这种机制是基于复杂逻辑的。幸运的是,在实际应用中,你不需要深究
这些细节,只需要掌握Powershell脚本签名的机制和过程。
准备一个合适的证书
  因为不能使用传统的纸质签名给Powershell脚本进行签名,你需要另一个工具“证书”。证书就像一把私有并且安全的钥匙。证书是你的个人电子身份特征。这把私密的钥匙确保只有证书的拥有者使用证书进行脚本签名。
  可以通过mmc添加管理单元查看证书,但是在Powershell中有专门查看证书的支持。可以通过虚拟驱动器cert:查看本机支持的证书。
创建自签名证书
  创建一个自签名证书,需要用到microsoft的工具,makecert.exe 。这个工具不能单独下载,但是它包含在微软的.NET framework中,如果你的电脑上已经安装了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 参数:1.3.6.1.5.5.7.3.3,不能是其它,否则证书的预期目的属性就不是代码签名了。
  上面创建的证书会自动保存在CurrentUserMy 路径下面。可以在Powershell中查看:
PS E:> ls cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"}  

  
    目录: Microsoft.PowerShell.SecurityCertificate::CurrentUserMy
  

  
Thumbprint                                Subject
  
----------                                -------
  
BA61AF0B8A856422AD9EF86104C8CEDB2583A21A  CN=MosserPowerShellTestCert
验证代码签名证书
  查看支持代码签名的证书
  查看证书的签发者,代表,序列号,指纹。
1234567891011121314151617181920## 查看预期目的为代码签名的证书:$certs = @(Dir cert:CurrentUserMy -codeSigningCert)"找到 {0} 个代码签名证书" -f $certs.count# 找到 1 个代码签名证书 ## 选择 刚才创建的证书$certificate=ls cert:CurrentUserMy | where {$_.subject -eq "CN=MosserPowerShellTestCert"} ## 证书的代表$certificate.subject# CN=MosserPowerShellTestCert ## 证书的签发者$certificate.issuer# CN=MosserPowerShellTestCert ## 证书的序列号,指纹$certificate |  select SerialNumber,Thumbprint | fl *# SerialNumber : C23F35EA85D9A5AB466C07A7C0469A78# Thumbprint   : 586A4332F0528867DA6A0900FCF0938EDD277E22声明一个证书受信任
  你会发现,在你指定证书的类型,颁发者的名称等信息后,证书的原始数据(RawData)会自动生成。这样你不能假冒别人生成一个证书,别人也不能假冒你的名字生成一个证书。如果通过Powershell查看之前生成的证书是否受信任,答案为否。
PS E:> $certificate.Verify()  
False
  为什么我们刚才生成的证书不受信任呢?我们可以通过一个简单的步骤找到答案。在.NET
中有一个方法:DisplayCertificate()可以通过对话框显示证书,位于System.Security.dll中。这个dll默认没有引
用,需要添加引用,之后显示证书对话框。
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)
DSC0000.jpg

  Powershell 查看证书 不受信任
  对话框提示:此CA根证书不受信任,要启用信任,请将该证书安装到”受信任的根证书颁发机构“存储区。
  所以接下来可以将该证书复制到受信任的存储区。可以通过certmgr.msc 手动操作,也可以通过Powershell自动化操作。
PS E:> $rootStore= New-Object system.security.cryptography.X509Certificates.x509Store("root","Curre  
ntuser")
  
$rootStore.Open("ReadWrite")
  
$rootStore.Add($certificate)
  
$rootStore.Close()
  在执行Add操作时,会有一个确认的对话框,确定即可。
  接下来我们查看一下验证信息。
PS E:> $certificate.Verify()  
True
给Powershell 脚本签名
  给Powershell脚本进行数字签名只需要两步:找的一个受信任的代码签名证书,剩下的工作请交给:Set-AuthenticodeSignature吧。
PS E:> 'Write-Host "我的第一个签名脚本"' > 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 "我的第一个签名脚本"
  

  
# 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
递归给所有脚本文件签名
  给当前文件下的所有脚本签名
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使用对话框选择证书
  如果机器上安装了代码签名的证书有许多,你可以通过friendName 或者证书的名称,证书的指纹,过滤一个证书供脚本签名。
Dir cert:CurrentUserMy |  
where {$_.subject -eq "CN=MosserPowerShellTestCert"}
  另一种方法是通过.NET中的内置的对话框进行选择。将查询到的证书传递给SelectFromCollection()方法,在在作此操作之前必须将证书放在一个特殊的集合中。
123456789101112131415# 对话框文本:$title = "可用的证书"$text = "请选择用于代码签名的证书:"# Find certificates:$certificates = Dir cert: -recurse -codeSigningCert# 加载 System.Security 类库# 将证书存放在特殊的集合(X509Certificate2Collection)中:[Reflection.Assembly]::LoadWithPartialName("System.Security")$collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection$certificates | ForEach-Object { $collection.Add($_) }# 显示选项:$certificate =[System.Security.Cryptography.x509Certificates.X509Certificate2UI]::`SelectFromCollection($collection, $title, $text, 0)# 使用选择的证书进行数字签名Set-AuthenticodeSignature -Certificate $certificate[0] -FilePath .firstSignScript.ps1
DSC0001.jpg

  Powershel l对话框选择 证书
Powershell脚本签名验证
  在脚本中签名到底能带来什么好处,那就是可以进行验证。可以手动验证,也可以自动验证。签名验证会告诉你脚本是否信任,或者是否包含了恶意篡改。
  用户自行验证:手动验证,可以检查一个脚本是否包含签名代码,签名者是谁?该签名者是否受信任。
  自动验证:如果你将Powershell的脚本执行策略设置为AllSigned. Powershell会在你尝试运行脚本时自动验证,代码和脚本签名是否一致。并且会询问签名者是否受信任。
手动验证
  Get-AuthenticodeSignature命令可以验证签名。例如创建一个脚本,不进行签名,通过该命令进行验证。属性StatusMessage会告诉你签名验证的结果。
"'未签名'" >notsign.ps1  
$checkResult=Get-AuthenticodeSignature .notsign.ps1
  
$checkResult.Status
  
NotSigned
  
$checkResult.StatusMessage
  
文件 E:notsign.ps1 未经数字签名。系统将不执行该脚本。有关详细信息,请参阅 "get-help about_signing"
  

  
$checkResult.Status.GetType().fullName
  
System.Management.Automation.SignatureStatus
  如果运行该未签名的脚本,也会收到错误提示信息,也就是StatusMessage中包含的信息。脚本的验证结果状态包括:
成员名称描述HashMismatch文件的哈希码和存储的签名不匹配Incompatible无法验证签名,因为与当前操作系统不兼容NotSigned文件没有签名NotSupportedFileFormat指定的文件格式不支持的系统签名。这通常意味着系统不知道如何签名或验证文件的类型。NotTrusted证书的发布者在系统中不受信任.UnknownError文件签名无效Valid该文件有一个有效的签名。这意味着只有签名的语法上是合法的。这并不意味着信任。自动验证
  你不须要去验证脚本的签名,当你运行一个脚本时,Powershell会自动验证。即使验证过的脚本,如果有部分内容更新,自动验证也会给出警告。
  在用户将脚本执行策略设置为AllSigned和RemoteSigned时,自动验证就会激活,如果将执行策略设置为AllSigned,所有的脚本都会验证。如果你选择RemoteSigned,从网络上下载的脚本执行会提示需要签名。
# 设置 ExecutionPolicy 为 AllSigned. 所有  
# 脚本必须有正确的签名:
  
Set-ExecutionPolicy AllSigned
  
# 创建一个没有签名的脚本.
  
# 该脚本不会执行:
  
无法加载文件 E:unSigned.ps1。文件 E:unSigned.ps1 未经数字签名。系统将不执行该脚本。有关详细信息,
  
请参阅 "get-help about_signing"。。
  
所在位置 行:1 字符: 15
  
+ .unSigned.ps1 <

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-561668-1-1.html 上篇帖子: 一些powershell实用范例 下篇帖子: powershell脚本自动检核DAG
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表