尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Windows代码签名证书免费获取与自签名实战指南

Windows代码签名证书免费获取与自签名实战指南 1. 项目概述为什么我们需要免费的Windows代码签名证书如果你是一个独立开发者或者在一个小团队里鼓捣一些Windows桌面工具、脚本或者驱动那你大概率遇到过这个让人头疼的弹窗“Windows已保护你的电脑”或者“Windows无法验证此文件的发布者”。这个SmartScreen筛选器或者驱动签名警告就像一个尽职尽责但过于严格的保安把你辛辛苦苦开发的软件拦在了用户门外。用户需要多点击几次“更多信息”-“仍要运行”体验非常糟糕甚至会让用户对你的软件安全性产生怀疑。这就是代码签名证书的用武之地。简单来说它就像软件的“身份证”和“公章”。微软信任的证书颁发机构CA核实了你的身份后给你颁发这张“身份证”。当你用它对你的软件.exe, .dll, .msi, .sys等进行数字签名后Windows系统就能认出“哦这是那个经过验证的‘张三’发布的软件不是来路不明的可疑文件。” 于是烦人的警告消失了软件的安装和启动流程变得顺畅专业度也瞬间提升。然而问题来了。一张由商业CA如DigiCert, Sectigo, GlobalSign颁发的OV组织验证或EV扩展验证代码签名证书价格不菲动辄每年几百到几千美元。对于个人开发者、学生、开源项目或者仅仅是做内部工具的小团队来说这是一笔不小的开销。我们需要的往往不是那种能消除所有警告如EV证书的即时信誉的顶级证书而是一个能解决基本“身份标识”问题、让软件看起来更可信的入门方案。于是“完全免费的Windows代码签名证书”就成了一个极具吸引力的探索方向。请注意这里讨论的“免费”路径核心是利用微软、开源社区或某些特定项目提供的合法免费资源绝非破解、盗用或伪造证书。这些方法各有其适用范围、限制和注意事项接下来我将为你一一拆解。2. 核心思路拆解免费的“身份证”从哪里来在付费商业证书之外我们主要有三条合法的免费路径可以探索。每一条路通向的“目的地”和需要的“通行证”都不一样。2.1 路径一开源项目与社区证书这是最“名正言顺”的免费路径之一。一些开源基金会或社区为了扶持开源软件发展会提供免费的代码签名证书给符合条件的项目。典型代表SSL.com 的开源项目免费证书。SSL.com 有一个“FOSSFree and Open Source Software代码签名证书”计划。符合条件的开源项目可以申请一张为期一年的免费OV代码签名证书到期后可以续期。工作原理你作为项目维护者需要证明你的项目是真正开源且活跃的通常通过GitHub仓库、许可证、社区活动等来证明。CA会对你的项目而非你个人进行验证。证书颁发后你可以用它来签署该项目的发布文件。优点证书来自受信任的根证书机构签名被Windows广泛接受。完全免费且合法合规。缺点申请有门槛仅限于被认可的开源项目。证书绑定的是项目身份不能用于签署个人或商业闭源软件。申请和审核需要时间。2.2 路径二利用平台开发者账户微软和苹果等平台方为其生态内的开发者提供了签名机制虽然不完全等同于传统的代码签名证书但能达到类似的效果。典型代表微软 Windows Hardware Developer Program。对于开发Windows硬件驱动.sys文件的开发者微软提供了一个“Windows Hardware Developer Program”。加入该计划可能需要缴纳一次性费用但有时有免费活动后你可以使用微软提供的“交叉签名”服务为你的驱动获取有效的签名从而解决Windows 10/11上令人崩溃的“驱动需要数字签名”问题。工作原理你将未签名的驱动提交到微软的门户网站微软使用其受信任的证书对你的驱动进行签名。这个过程确保了驱动文件的完整性和发布源通过你的开发者账户关联。优点对于驱动开发者来说是“官方解决方案”签名有效性有保障。缺点主要针对驱动文件对普通的.exe/.msi应用程序不适用。流程相对复杂且主要面向硬件开发者。2.3 路径三自签名证书与内部信任这是技术门槛最低、最灵活但也是适用范围最受限的方法。工作原理你可以使用OpenSSL、PowerShell或Windows SDK中的工具自己生成一个“根证书”和“代码签名证书”。这个证书完全由你控制无需向任何第三方CA付费。优点完全免费随时创建可以设置任意有效期和主题信息。非常适合内部开发、测试环境或者在一个可控的局域网内部分发软件。核心限制与挑战自签名证书的“根”不在微软的受信任根证书存储列表中。因此默认情况下任何安装了该软件的电脑都不会信任你的签名。用户会看到“未知发布者”的警告。如何让它“有用”要让自签名证书发挥作用你必须将你的自签名“根证书”手动安装到目标计算机的“受信任的根证书颁发机构”存储区。之后由该根证书签发的任何代码签名证书都会被该计算机信任。注意这显然不适用于公开发布的软件。你不可能要求每个用户都去手动安装一个根证书。因此这种方法仅适用于1) 企业内网统一部署2) 你自己管理的少数几台测试机3) 给特定客户交付项目时作为交付流程的一部分指导客户安装根证书。3. 实操指南以OpenSSL创建自签名证书为例虽然自签名证书公网分发不行但它是理解代码签名原理和进行开发测试的绝佳实践。下面我们一步步用OpenSSL来创建一套自签名证书并签名一个.exe文件。3.1 环境与工具准备安装OpenSSL前往OpenSSL官网下载Windows版本安装或者使用Git for Windows里自带的Git Bash环境它包含了OpenSSL。确保安装后可以在命令行中运行openssl version。准备待签名的文件我们用一个简单的“HelloWorld.exe”程序作为示例。你可以用任何编程语言编译一个甚至是一个空的可执行文件。签名工具我们将使用Windows SDK中的signtool.exe。如果你安装了Visual Studio它通常位于C:\Program Files (x86)\Windows Kits\10\bin\版本号\x64\或x86\目录下。也可以单独安装Windows SDK来获取它。3.2 生成自签名根证书和代码签名证书打开命令行建议用Git Bash或PowerShell依次执行以下命令。第一步生成根证书的私钥和证书请求CSR# 生成一个2048位的RSA私钥用于根证书 openssl genrsa -out rootCA.key 2048 # 使用该私钥创建一个自签名的根证书有效期10年 openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt -subj /CNMyTestRootCA-subj参数设置了证书的主题这里我们只设置了通用名称CN为“MyTestRootCA”。在实际内部使用中你可以设置更详细的组织信息如/CCN/STBeijing/LBeijing/OMyCompany/CNMyCompanyRootCA。第二步生成代码签名证书的私钥和CSR# 生成用于代码签名证书的私钥 openssl genrsa -out codesign.key 2048 # 创建证书签名请求 openssl req -new -key codesign.key -out codesign.csr -subj /CNMyTestSoftware第三步使用根证书为代码签名请求签发证书我们需要创建一个扩展配置文件来指明这是代码签名证书。创建一个文本文件命名为v3.ext内容如下authorityKeyIdentifierkeyid,issuer basicConstraintsCA:FALSE keyUsage digitalSignature, nonRepudiation, keyEncipherment extendedKeyUsage codeSigning subjectKeyIdentifierhash然后执行命令openssl x509 -req -in codesign.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out codesign.crt -days 365 -sha256 -extfile v3.ext现在我们得到了关键文件rootCA.crt自签名根证书。codesign.crt和codesign.key由上述根证书颁发的代码签名证书及其私钥。第四步将证书转换为PFX格式signtool工具通常需要PKCS#12格式.pfx的证书文件它包含了证书和私钥。openssl pkcs12 -export -out codesign.pfx -inkey codesign.key -in codesign.crt -password pass:YourPassword请将YourPassword替换为一个强密码并牢记它。3.3 使用signtool进行数字签名首先将根证书rootCA.crt安装到本机的“受信任的根证书颁发机构”。这只是为了让本机信任后续的签名用于测试。双击rootCA.crt- 点击“安装证书” - 选择“本地计算机” - 选择“将所有的证书都放入下列存储” - 浏览选择“受信任的根证书颁发机构” - 完成。然后使用signtool进行签名# 切换到signtool所在目录或将其加入系统PATH cd C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64 # 对HelloWorld.exe进行签名 signtool sign /f C:\path\to\your\codesign.pfx /p YourPassword /t http://timestamp.digicert.com C:\path\to\your\HelloWorld.exe/f指定.pfx证书文件路径。/p指定.pfx文件的密码。/t添加时间戳。这是一个极其重要的步骤。时间戳服务如DigiCert, Sectigo提供的免费服务会在签名中嵌入一个权威时间戳。这样即使你的证书在未来过期了系统也会根据签名时的时间戳来验证只要签名时证书是有效的该签名就永远有效。没有时间戳的签名一旦证书过期签名即刻失效。最后是要签名的文件路径。签名完成后右键点击HelloWorld.exe- 属性 - 数字签名你应该能看到签名信息发布者显示为“MyTestSoftware”。4. 深入解析签名背后的原理与关键参数仅仅会操作还不够理解背后的原理和每个参数的意义能让你在遇到问题时游刃有余。4.1 数字签名到底做了什么当你对一个文件进行代码签名时主要发生了三件事哈希计算工具如signtool会计算整个文件内容的哈希值通常是SHA256。这个哈希值就像文件的“数字指纹”任何微小的改动都会导致哈希值巨变。加密哈希使用你的代码签名证书对应的私钥对这个“指纹”进行加密。加密后的结果就是数字签名。嵌入信息将数字签名、你的证书包含公钥以及其他信息如时间戳一起写入到可执行文件的一个特定区域通常是文件的尾部或一个附加的签名块。当用户运行这个文件时Windows系统会重新计算文件的哈希值。用你证书里的公钥解密附带的数字签名得到原始的哈希值。对比两个哈希值。如果一致证明文件自签名后未被篡改。检查证书链你的代码签名证书是否由一个受信任的根证书签发证书是否在有效期内是否被吊销如果所有检查都通过Windows就会放心地显示已知的发布者名称而不是安全警告。4.2 时间戳Timestamp为什么是必选项这是一个新手极易忽略但后果严重的关键点。假设你的证书2024年12月31日过期。没有时间戳你在2024年12月30日签名了一个软件。到了2025年1月1日你的证书过期了。此时任何用户尝试安装或运行这个软件Windows都会因为证书过期而判定签名无效导致警告甚至阻止运行。有时间戳同样在2024年12月30日签名并添加了来自DigiCert的时间戳。到了2025年Windows验证时会向时间戳服务器查询“在2024年12月30日这个时间点这个签名证书有效吗” 时间戳服务器回答“有效。” 于是Windows就认可这个签名是长期有效的。因此永远记得在签名命令中加上/t参数。常用的免费时间戳服务器有http://timestamp.digicert.comhttp://timestamp.sectigo.comhttp://rfc3161timestamp.globalsign.com/advanced4.3 哈希算法与双重签名为了兼容新旧系统有时需要进行双重签名。/fd sha256指定文件哈希算法为SHA256。这是当前的标准安全性高。/fd sha1指定为SHA1。SHA1已被认为不安全但在一些非常古老的系统如Windows XP SP2以前上可能还需要。除非有极端兼容性要求否则不应使用SHA1。双重签名命令示例signtool sign /f mycert.pfx /p password /fd sha256 /t http://timestamp.digicert.com /d My App /du http://www.myapp.com myapp.exe signtool sign /as /f mycert.pfx /p password /fd sha1 /t http://timestamp.digicert.com myapp.exe第一条命令用SHA256签名并添加描述和URL。第二条命令中的/as参数表示“附加签名”即在已有SHA256签名的基础上再附加一个SHA1签名。5. 进阶场景与疑难问题排查掌握了基础操作后我们来看看更复杂的场景和那些让人抓狂的报错。5.1 驱动.sys签名与测试模式驱动程序对签名要求更严格。即使使用自签名证书在64位Windows 10/11上默认设置下也无法加载未经微软交叉签名的驱动。对于开发和测试通常有两种方法禁用驱动强制签名临时在高级启动选项中选择“禁用驱动程序强制签名”。但这只是临时解决方案重启后可能失效且降低系统安全性。启用测试模式这是更规范的开发测试方法。以管理员身份打开命令行输入bcdedit /set testsigning on重启电脑。你会在桌面右下角看到“测试模式”的水印。在测试模式下系统允许加载由“受信任的根证书”签名的驱动即使该根证书是自签名的。因此你需要将你的rootCA.crt安装到测试机的“受信任的根证书颁发机构”。用你的codesign.pfx为驱动文件签名。此时驱动应该可以正常加载了。重要测试完成后务必关闭测试模式bcdedit /set testsigning off并重启。5.2 PowerShell脚本签名PowerShell脚本.ps1也可以签名以绕过执行策略限制。过程类似但使用Set-AuthenticodeSignaturecmdlet。# 获取证书对象 $cert Get-PfxCertificate -FilePath C:\path\to\codesign.pfx -Password (ConvertTo-SecureString -String YourPassword -Force -AsPlainText) # 为脚本签名 Set-AuthenticodeSignature -FilePath C:\script.ps1 -Certificate $cert -TimestampServer http://timestamp.digicert.com签名后在要求“AllSigned”执行策略的机器上该脚本可以直接运行。5.3 常见错误与解决方案速查表错误现象可能原因排查与解决步骤SignTool Error: No certificates were found that met all the given criteria.1. .pfx文件路径或密码错误。2. .pfx证书已损坏或格式不对。3. 证书不包含代码签名增强密钥用法EKU。1. 检查文件路径和密码确保无误。2. 尝试用openssl pkcs12 -info -in codesign.pfx查看证书信息确认是否包含私钥和证书。3. 用certutil -dump codesign.crt查看证书详情确认Extended Key Usage包含Code Signing (1.3.6.1.5.5.7.3.3)。签名成功但运行时仍显示“未知发布者”。1. 签名证书的根证书不在系统的“受信任的根证书颁发机构”存储中。2. 签名没有添加时间戳且证书已过期。1. 对于自签名证书必须在目标机器安装根证书rootCA.crt。2. 检查签名属性中的时间戳是否有效。用signtool verify /pa /v yourfile.exe验证签名。SignTool Error: The specified timestamp server either could not be reached or returned an invalid response.时间戳服务器URL错误或网络不通。1. 检查URL拼写确保是http://开头。2. 尝试更换一个时间戳服务器如从DigiCert换到Sectigo。3. 检查防火墙或代理设置。驱动安装失败提示“Windows 无法验证此设备所需的驱动程序的数字签名”。1. 驱动未签名。2. 使用了自签名证书但未在测试模式下运行或根证书未安装。3. 驱动文件在签名后被修改。1. 用signtool verify /kp yourdriver.sys验证驱动签名是否有效/kp检查内核模式签名。2. 确认测试模式已开启桌面有水印并确认根证书已正确安装到“本地计算机”的受信任根存储。3. 重新签名驱动。签名验证失败错误代码 0x800B0109证书链中的证书不受信任。证书链不完整或根证书不受信任。这是自签名证书的典型表现。确保完整的证书链从你的代码签名证书到根证书都被信任。对于自签名就是安装根证书。对于商业证书有时需要中间证书确保它们被安装在“中间证书颁发机构”存储。5.4 关于“Windows健康状况和优化体验”等无关进程的说明在搜索相关热词时你可能会看到“windows健康状况和优化体验可以禁用吗”、“windows安全中心英文改中文”等问题。这些通常与代码签名无关是Windows系统自身的组件或设置。“Windows 健康状况和优化体验”这是一个系统服务用于收集诊断数据以提供体验改进建议。如果你在任务管理器中看到相关进程占用资源可以在“服务”应用中找到DiagTrack或dmwappushservice服务将其启动类型改为“禁用”。但这可能会影响Windows Update的某些功能或个性化建议。安全警告语言SmartScreen筛选器或安全中心的警告语言跟随系统显示语言。要改变它你需要更改整个Windows系统的显示语言设置 - 时间和语言 - 语言和区域。6. 总结与个人实践心得探索免费的Windows代码签名证书本质上是在“成本”、“便利性”和“信任范围”之间寻找一个平衡点。对于个人学习、内部工具、特定客户交付或开源项目利用自签名证书或社区免费资源是完全可行且具有很高价值的。它能让你深入理解PKI公钥基础设施和代码签名的运作机制这是比单纯购买一张证书更宝贵的经验。在我自己的实践中对于内部使用的自动化脚本和小工具我维护一个自签名的根证书。在新员工电脑配置时将安装这个根证书作为标准步骤之一。这样所有内部签名的软件都能无缝运行。对于打算公开发布的开源小工具我会优先考虑像SSL.com FOSS计划这样的免费资源如果不符合条件我会在项目主页清晰说明软件未进行商业签名并提供SHA256校验和供用户验证文件完整性这也是一种建立信任的方式。最后一个非常重要的提醒请务必妥善保管你的私钥.key或.pfx文件和密码。私钥一旦泄露他人就可以冒充你的身份对恶意软件进行签名。对于自签名证书如果私钥泄露唯一的补救措施就是重新生成一套全新的根证书和子证书并在所有已部署的机器上更新受信任的根证书这将是一个巨大的工程。因此对待私钥要像对待银行密码一样谨慎。
返回列表