Add-Type -AssemblyName Microsoft.VisualBasic # 提示输入证书名称 $CertName = [Microsoft.VisualBasic.Interaction]::InputBox( "请输入证书名称(如果系统中已有相同名称的证书,旧证书将被删除):", "输入证书名称(必须为英文,且无特殊字符)", "sidoc" ) if ([string]::IsNullOrWhiteSpace($CertName)) { Write-Host "❌ 未输入证书名称,脚本终止。" -ForegroundColor Red exit 1 } # 提示输入导出密码 $Password = [Microsoft.VisualBasic.Interaction]::InputBox( "请输入用于导出 .pfx 文件的密码:", "输入证书密码", "123456" ) if ([string]::IsNullOrWhiteSpace($Password)) { Write-Host "❌ 未输入密码,脚本终止。" -ForegroundColor Red exit 1 } # 构造参数 $Subject = "CN=$CertName" $CertStore = "Cert:\CurrentUser\My" $OutputPath = (Get-Location).Path $PfxFile = Join-Path $OutputPath "$CertName-code-sign.pfx" Write-Host "`n🔐 正在生成自签名证书: $Subject`n" -ForegroundColor Cyan # 清除旧的同名证书 # 可同时存在多个同名证书,这会造成混乱,因此要删除旧的同名证书; $oldCerts = Get-ChildItem -Path $CertStore | Where-Object { $_.Subject -eq $Subject } if ($oldCerts.Count -gt 0) { Write-Host "🧹 发现旧证书,正在删除..." -ForegroundColor Yellow $oldCerts | Remove-Item } # 创建证书(有效期10年) $cert = New-SelfSignedCertificate ` -Type CodeSigningCert ` -Subject $Subject ` -CertStoreLocation $CertStore ` -NotAfter (Get-Date).AddYears(10)` -KeyUsageProperty Sign ` -KeyUsage DigitalSignature # 创建证书(有效期2年,符合最佳实践) $cert = New-SelfSignedCertificate ` -Type CodeSigning ` -Subject $Subject ` -CertStoreLocation $CertStore ` -NotAfter (Get-Date).AddYears(2) ` -KeyUsage DigitalSignature ` -KeyUsageProperty Sign ` -KeyAlgorithm RSA ` -KeyLength 2048 ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3") ` -FriendlyName "$CertName Code Signing Certificate" if (-not $cert) { Write-Error "❌ 证书生成失败。" exit 1 } # 导出为 .pfx 文件 $pfxSecurePassword = ConvertTo-SecureString -String $Password -Force -AsPlainText Export-PfxCertificate ` -Cert $cert ` -FilePath $PfxFile ` -Password $pfxSecurePassword # 显示结果信息 Write-Host "`n✅ 成功生成签名证书并导出为 .pfx 文件:" -ForegroundColor Green Write-Host "📁 文件路径: $(Resolve-Path $PfxFile)" Write-Host "🔑 指纹(Thumbprint): $($cert.Thumbprint)" Write-Host "📅 有效期: $($cert.NotBefore) ~ $($cert.NotAfter)" Write-Host "🔒 导出密码: $Password`n" # 保持窗口显示(适合双击运行) Pause