提供CertificateTemplate和SAN属性时,如何使用certreq.exe签名CSR?

问题描述

欢迎大家!

我目前正在尝试使用Powershell和certreq.exe自动执行严格的内部SSL证书签名。此时,我可以创建有效的证书,但是-attrib选项使我有些头疼。

我将自动创建的CSR发送到我的CA,并且获得了有效的证书,但是缺少前3个SAN条目IPAddress=$iLOIP&DNS=$iLOIP&DNS=$hostname。但是,存在最后一个DNS=iLOFQDN)。我正在使用此确切命令:

certreq.exe -submit -config $certificateserver -attrib "CertificateTemplate:$certificatetemplate\nsan:IPAddress=$iLOIP&DNS=$iLOIP&DNS=$hostname&DNS=$iLOFQDN" "$scriptpath\currentcsr.txt" "$scriptpath\currentcert.cer"

我不确定语法,但是奇怪的是,如果没有\nCertificateTemplate:$certificatetemplate间的SAN:,它就无法工作。谷歌搜索问题时,我发现的很早,但是它并不能解决我的所有问题。

很遗憾,我无法使用.inf文件来输入SAN条目。

现在我的问题是: -attrib字段中使用的正确语法是什么? 是否有可能不指定模板?我是否使工作复杂化了很多,并且已经有工具可以完成所有这一切?

解决方法

继续我的评论,这是一个预先构建的PowerShell脚本,用于请求SAN证书。

powershell request a SAN cert

Certificate with SAN using Powershell - with Import/Export

此脚本使用Powershell通过SAN创建证书(主题 备用名称),使用特定网站将请求提交给CA 服务器模板,并相应地发布到服务器/工作站。 已更新,以允许使用通配符CN。

Download: New-CACertificate.ps1

<# 
 
.SYNOPSIS 
Script to ease the pain of creating/submitting/automating the process of creating a certificate for on-prem CA 
 
.DESCRIPTION 
Required Variables: Subject,Exportable,SAN1,Template. Up to 5 SANs can be included in this script. More can be added if desired. User must have privileges to submit / create certificate template.  
 
.EXAMPLE 
./get-certificate-inf.ps1 -Subject contoso.com -Exportable $false -Template Server -SAN1 contoso.com -SAN2 www.contoso.com -SAN3 devsite.constoso.com 
 
.NOTES 
Variables that Require user modification to the script: See "Subject Variables" Section. 
 
#> 
 
 
[CmdletBinding()] 
Param( 
[Parameter(Mandatory=$True)] 
[string]$Subject,[Parameter(Mandatory=$True)] 
[string]$Exportable,[Parameter(Mandatory=$True)] 
[string]$SAN1,[Parameter(Mandatory=$False)] 
[string]$SAN2,[Parameter(Mandatory=$False)] 
[string]$SAN3,[Parameter(Mandatory=$False)] 
[string]$SAN4,[Parameter(Mandatory=$False)] 
[string]$SAN5,[Parameter(Mandatory=$True)] 
[string]$Template 
 
) 
$ErrorActionPreference = 'Inquire' 
 
## Gathering Logic for SAN 
$SAN = '' 
if ($SAN2) 
{ 
    $SAN +="&dns=$SAN2" 
} 
else{} 
 
if ($SAN3) 
{ 
    $SAN +="&dns=$SAN3" 
} 
else{} 
 
if ($SAN4) 
{ 
    $SAN +="&dns=$SAN4" 
} 
else{} 
 
if ($SAN5) 
{ 
    $SAN +="&dns=$SAN5" 
} 
else{} 
 
$FullSAN ="{text}dns=$SAN1$SAN" 
 
## Required Because Powershell interprets $Windows as a variable not a string 
$Windows = '$Windows' 
 
$inputfiletemplate = @" 
[Version]  
Signature="$Windows NT$" 
 
##Enter Subject Variables Here and uncomment: 
# $O = [organization] 
# $OU = [Organizational Unit] 
# $E = [email] 
# $L = [locality] 
# $ST = [state] 
# $C = [country] 
 
[NewRequest]  
Subject = "CN=$Subject,O=$O,OU=$OU,E=$E,L=$L,ST=$ST,C=$C"   ; For a wildcard use "CN=*.CONTOSO.COM" for example 
Exportable = $Exportable                  ; Private key is not exportable  
KeyLength = 2048                    ; Common key sizes: 512,1024,2048,4096,8192,16384  
KeySpec = 1                         ; AT_KEYEXCHANGE  
KeyUsage = 0xA0                     ; Digital Signature,Key Encipherment  
MachineKeySet = True                ; The key belongs to the local computer account  
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"  
ProviderType = 12  
SMIME = FALSE  
RequestType = CMC 
 
; At least certreq.exe shipping with Windows Vista/Server 2008 is required to interpret the [Strings] and [Extensions] sections below 
 
[Strings]  
szOID_SUBJECT_ALT_NAME2 = "2.5.29.17"  
szOID_ENHANCED_KEY_USAGE = "2.5.29.37"  
szOID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"  
szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2" 
 
[Extensions]  
%szOID_SUBJECT_ALT_NAME2% = "$FullSAN"  
%szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_PKIX_KP_SERVER_AUTH%,%szOID_PKIX_KP_CLIENT_AUTH%" 
 
[RequestAttributes]  
CertificateTemplate=$Template 
"@ 
 
### Gathering Certificate information ### 
 
$filename = $Subject.Substring(0,3) 
 
### Make allowance for wildcard CNs 
 
    if ($filename -like "*") 
        { 
            Write-Host "Hang on...have to create a new filename..." 
            $filename = (-join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_})) 
        } 
        else  
        { 
        #Do Nothing     
        } 
 
$inputfiletemplate | Out-File "$filename.inf" 
 
Write-Host "Generating request" 
 
### End of Gathering Certificate information ### 
 
# Using Certreq to request a new certificate with information file and request 
& "C:\Windows\System32\certreq.exe" "-new" "$filename.inf" "$filename.req" 
 
# Submitting Request to CA with request and saving file as a .cer 
Write-Host "Submitting request to CA" 
& "C:\Windows\System32\certreq.exe" "-submit" "$filename.req" "$filename.cer" 
 
# Accepting the certificate from SubCA 
& "C:\Windows\System32\certreq.exe" "-accept" "$filename.cer" 
Write-Host "Certificate Imported Successfully" 
 
# File cleanup 
Write-Host "Cleaning up files generated" 
Remove-Item "$filename.*" -Force 
 
# Asking if you would like to export the certificate  
if ($Exportable -eq $TRUE) 
{ 
    if((Read-Host -Prompt "Do you want to export the certificate? Y\N") -eq "y"){ 
#Show certifiate store  
Write-Host "Fetching Certificates in store for you..." 
get-childitem -Path Cert:\LocalMachine\my | Format-list subject,thumbprint 
 
#Ask user to copy thumbprint to console 
Write-Host "Please copy the thumbprint to export" 
$thumbprint = Read-Host -Prompt "Please paste the desired thumbprint here" 
 
#Export certificate with password 
get-childitem -Path Cert:\LocalMachine\my\$thumbprint | Export-PfxCertificate -Password (read-host -Prompt "Please type your password" -AsSecureString) -ChainOption EndEntityCertOnly -NoClobber -FilePath (read-host -Prompt "Give the PFX a filename with .pfx") 
"`nExport Successful... 'till next time." 
    } 
} 
else 
{ 
    "Mission Complete!" 
}