如何为 IIS 网站创建具有主题备用名称 (SAN) 的自签名 SSL 证书

如何为 IIS 网站创建具有主题备用名称 (SAN) 的自签名 SSL 证书

有谁知道如何创建用于具有主题备用名称 (SAN) 的 IIS (7) 的自签名 SSL 证书?我需要证书能够验证主机名和 IP 地址,如下所示:

  • CN=我的服务器名称
  • IP SAN:192.168.2.2

我一直在关注的一些事情:

  • Windows SDK:makecert.exe(不支持 SAN)

  • Windows API CertEnroll(服务器 2008):使用 PowerShell 脚本(我已经能够使其与 IIS 一起工作,但是当我将证书导出到 Java 密钥库(必须)时,我收到错误 keytool 错误:'java.lang.Exception:输入不是 X.509 证书')

以下是使用 CertEnroll 的 PowerShell 脚本示例:http://blogs.technet.com/b/vishalagarwal/archive/2009/08/22/generating-a-certificate-self-signed-using-powershell-and-certenroll-interfaces.aspx

  • OpenSSL:我还没有研究过这个...

如果我可以使用 CertEnroll API 通过 PowerShell 脚本创建 Java 可以识别的证书,那就太好了,但目前任何可行的方法我都乐意听到。

答案1

我找到了一种使用 OpenSSL 来实现这一点的方法。我原本希望使用 CertEnroll,但由于它给我带来了与 Java 的互操作性问题,所以我只打算使用 OpenSSL。

以下是我使用 OpenSSL 为 IIS 创建具有主题备用名称的证书的方法。

首先创建一个 OpenSSL 配置文本文件:

[req]
distinguished_name  = req_distinguished_name
x509_extensions     = v3_req
prompt              = no
[req_distinguished_name]
C           = US
ST          = VA
L           = SomeCity
O           = MyCompany
OU          = MyDivision
CN          = ANDY
[v3_req] 
keyUsage           = keyEncipherment, dataEncipherment
extendedKeyUsage   = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = andy
DNS.2 = 192.168.2.12
IP.1 = 192.168.2.12
IP.2 = 192.167.20.1

然后运行以下 OpenSSL 命令:

openssl.exe req -x509 -nodes -days 730 -newkey rsa:2048 -keyout C:\cert.pem -out C:\cert.pem -config C:\PathToConfigFileAbove.txt

openssl.exe pkcs12 -export -out C:\cert.pfx -in C:\cert.pem -name "My Cert" -passout pass:mypassword

这将在 PFX 文件中创建一个证书,该文件可以导入到 IIS。我使用 powershell 自动执行此操作,如下所示:

    # Get the certificate from the PFX file.
$pfxcert = new-object system.security.cryptography.x509certificates.x509certificate2
$pfxcert.Import(
    "C:\cert.pfx",
    "mypassword",
    [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor `
    [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
)

    # Add the certificate to the windows stores.
Get-Item -Path cert:\LocalMachine\My, cert:\LocalMachine\root | ForEach-Object {
    $store = $_
    $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
    $store.Add($pfxcert)
    $store.Close()
}

Add-PSSnapin -Name WebAdministration # IIS 7 Powershell module.
Push-Location -Path IIS:\SslBindings

    # Create new IIS SSL bindings.
Get-Item -Path "cert:\LocalMachine\My\$($pfxcert.Thumbprint)" | New-Item "0.0.0.0!443"

答案2

Java 密钥工具对于允许导入的内容非常挑剔。不过,通过 powershell 构建的证书应该可以正常工作,只需稍加修改即可。

证书现在是什么格式?如果您已从 Windows 证书存储中导出,则可能是 .pfx;您需要转换为 PEM 编码的 x509 证书:

openssl pkcs12 -in /path/to/certbundle.pfx -out /public/key/path/certificate.crt -nokeys
openssl pkcs12 -in /path/to/certbundle.pfx -out /private/key/path/certificate.key -nocerts -nodes

从那里,您将要检查文件的实际内容 - 这些 Windows 证书包括该-----BEGIN CERTIFICATE-----部分上方的“Bag Attributes”部分,keytool 解析器喜欢阻塞该部分 - 请随意删除它,以便文件看起来就像这样,没有其他内容:

/public/key/路径/certificate.crt

-----BEGIN CERTIFICATE-----
MIIAAAA........
-----END CERTIFICATE-----

/priv/key/path/certificate.key

-----BEGIN RSA PRIVATE KEY-----
MIIAAAA........
-----END RSA PRIVATE KEY-----

这些证书文件应该更适合通过 java keytool 导入。

答案3

我以为 SAN 也不支持使用 makecert,但后来我发现这个博客

似乎您可以通过使用多个通用名称来获得与使用 SAN 类似的功能。例如makecert -n "CN=CertName;CN=pseudoSAN"

或者在你的例子中"CN=Andy;CN=192.168.2.12"

答案4

2021 年更新。

现在可以使用单个命令行完成此操作,例如:

openssl req -new -x509 -nodes -sha256 -days 365 -subj "/C=GB/CN=blah" -addext  "subjectAltName = DNS:example.net,DNS:*.example.net,IP:192.168.2.12" -newkey rsa:2048 -keyout key.pem -out req.pem

来源:openssl req 手册页

相关内容