You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell创建含PRINTABLE_STRING等指定编码字段的自签名证书

实现方法

直接使用New-SelfSignedCertificate无法指定DN字段的字符串编码格式,需要借助Windows的CertEnroll COM对象手动构建证书请求并生成证书,以此精准控制字段的编码类型。以下是具体步骤:

1. 通过CertEnroll COM对象生成指定编码的自签名证书

运行以下PowerShell脚本,我们将CN=wdac设置为PRINTABLE_STRING编码(如需IA5STRING或BMPSTRING,只需修改对应枚举值即可):

# 初始化CertEnroll核心对象
$enroll = New-Object -ComObject X509Enrollment.CX509Enrollment
$certReq = New-Object -ComObject X509Enrollment.CX509CertificateRequestCertificate

# 配置私钥参数(匹配需求的RSA 4096位)
$privateKey = New-Object -ComObject X509Enrollment.CX509PrivateKey
$privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
$privateKey.KeySpec = [X509Enrollment.X509KeySpec]::XCN_AT_KEYEXCHANGE
$privateKey.KeyLength = 4096
$privateKey.MachineContext = $false # 对应CurrentUser证书存储
$privateKey.ExportPolicy = [X509Enrollment.X509PrivateKeyExportFlags]::XCN_NCRYPT_ALLOW_EXPORT_FLAG
$privateKey.Create()

# 构建Subject/Issuer并指定编码为PRINTABLE_STRING
$distinguishedName = New-Object -ComObject X509Enrollment.CX500DistinguishedName
# 枚举值说明:XCN_CERT_NAME_STR_PRINTABLE=PRINTABLE_STRING,XCN_CERT_NAME_STR_IA5=IA5STRING,XCN_CERT_NAME_STR_BMP=BMPSTRING
$distinguishedName.Encode("CN=wdac", [X509Enrollment.X509NameFlags]::XCN_CERT_NAME_STR_PRINTABLE)

# 配置证书基础属性
$certReq.InitializeFromPrivateKey([X509Enrollment.X509CertificateEnrollmentContext]::ContextUser, $privateKey, "")
$certReq.Subject = $distinguishedName
$certReq.Issuer = $distinguishedName # 自签名证书,Issuer与Subject一致
$certReq.NotBefore = Get-Date
$certReq.NotAfter = (Get-Date).AddYears(5) # 有效期设为5年,可按需调整

# 设置SHA512哈希算法
$hashOid = New-Object -ComObject X509Enrollment.CObjectId
$hashOid.InitializeFromValue([X509Enrollment.ObjectId]::XCN_OID_SHA512)
$certReq.HashAlgorithm = $hashOid

# 添加代码签名扩展(满足WDAC规则要求)
$codeSignOid = New-Object -ComObject X509Enrollment.CObjectId
$codeSignOid.InitializeFromValue([X509Enrollment.ObjectId]::XCN_OID_CODE_SIGNING)
$ekuExtension = New-Object -ComObject X509Enrollment.CX509ExtensionEnhancedKeyUsage
$ekuExtension.InitializeEncode($codeSignOid)
$certReq.X509Extensions.Add($ekuExtension)

# 生成并安装证书到CurrentUser\My存储
$enroll.InitializeFromRequest($certReq)
$certBase64 = $enroll.CreateRequest([X509Enrollment.EnrollmentRequestFlags]::XCN_CERTREQ_INCLUDE_CHAIN)
$enroll.InstallResponse([X509Enrollment.InstallResponseRestrictionFlags]::XCN_CERT_INSTALL_RESPONSE_ALLOW_UNTRUSTED_CA, $certBase64, [X509Enrollment.EncodingType]::XCN_CRYPT_STRING_BASE64, "")

2. 验证编码是否符合要求

用certutil工具导出并查看证书字段编码:

# 定位目标证书
$targetCert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Subject -eq "CN=wdac"}
# 导出为DER格式证书文件
Export-Certificate -Cert $targetCert -FilePath "C:\temp\wdac-cert.cer" -Type CERT
# 查看证书详情,检查编码类型
certutil -dump "C:\temp\wdac-cert.cer"

在输出的Subject或Issuer区域,会明确显示PRINTABLE_STRING(或你指定的编码类型),而非UTF-8对应的UTF8String。

关键注意事项

  • 自签名证书的Subject与Issuer编码需保持一致,脚本中通过复用同一个CX500DistinguishedName对象实现这一点。
  • 若需切换编码,直接替换XCN_CERT_NAME_STR_PRINTABLE为对应枚举值即可:IA5STRING用XCN_CERT_NAME_STR_IA5,BMPSTRING用XCN_CERT_NAME_STR_BMP。
  • 脚本中配置的密钥规格、哈希算法、代码签名扩展均符合WDAC签名证书的要求,可根据实际场景调整有效期等参数。

内容的提问来源于stack exchange,提问作者user20682592

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:35:28