我在Windows Server Enterprise 2008上使用IIS 7生成一个用于IIS的自签名证书(基本上是一键式按钮)。
但是,即使我将此证书导出并添加到Windows客户端的curl-ca-bundle.crt,它和openssl.exe都不会正确验证证书:
openssl s_client -CAfile curl-ca-bundle.crt -showcerts -connect myserver.ad.pri:443
CONNECTED(00000003)
depth=0 /CN=myserver.ad.pri
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /CN=myserver.ad.pri
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=myserver.ad.pri
i:/CN=myserver.ad.pri
-----BEGIN CERTIFICATE-----
MIIDADCCAeigAwIBAgIQTi9gdBLdo6pJ1h4Zljr/wzANBgkqhkiG9w0BAQUFADAp
....
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=myserver.ad.pri
issuer=/CN=myserver.ad.pri
---
No client certificate CA names sent
---
SSL handshake has read 924 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Start Time: 1377728216
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
read:errno=104
我使用IE将证书导出到Base-64编码,这是可以作为PEM的openssl可读的: openssl x509 -inform PEM -in myserver.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4e:2f:60:74:12:dd:a3:aa:49:d6:1e:19:96:3a:ff:c3
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=myserver.ad.pri
Validity
Not Before: Aug 26 15:38:46 2013 GMT
Not After : Aug 26 00:00:00 2014 GMT
Subject: CN=myserver.ad.pri
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
....
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment, Data Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha1WithRSAEncryption
...
-----BEGIN CERTIFICATE-----
....
使用相同的curl-ca-bundle.crt的openssl / curl将验证来自google.com:443等的证书就好了。
答案 0 :(得分:2)
我通过使用openssl创建自签名CA证书,然后创建服务器证书请求(也是在OpenSSL中,由于某种原因openssl不喜欢签署IIS生成的请求)解决了这个问题,并与前CA签名证书,然后出口到PKCS12。然后导入IIS。将CA证书添加到curl-ca-bundle.crt后,它将正确验证链:
生成CA:
openssl req -new -x509 -days 3650 -extensions v3_ca \
-keyout cakey.pem -out cacert.pem -config /etc/ssl/openssl.cnf \
-newkey rsa:2048
生成服务器密钥和签名请求:
openssl req -new -nodes -out server-csr.pem -keyout server-key.pem -newkey rsa:2048
与CA签署请求:
openssl ca -config /etc/ssl/openssl.cnf -cert cacert.pem -keyfile cakey.pem \
-out server-cert.pem -in server-csr.pem
将服务器证书导出到PKCS#12:
openssl pkcs12 -export -out server-key-cert.pfx \
-inkey server-key.pem -in server-cert.pem -certfile cacert.pem
将server-key-cert.pfx导入IIS。 (重新)将站点绑定的SSL绑定绑定到证书。
将cacert.pem附加到客户的curl-ca-bundle.crt。 openssl s_client -showcerts -CAfile curl-ca-bundle.crt -connect server:443的深度为0和1,将验证返回。
备注:确保在openssl.cnf的[usr_cert]部分下启用了keyUsage = nonRepudiation,digitalSignature,keyEncipherment,否则请求将不包含那些keyUsage,IIS会抱怨绑定。
答案 1 :(得分:2)
当我无法使用NodeJS HTTP(s)客户端连接到自我的IIS实例时,我也遇到了这个问题(我感到非常惊讶,更多的人还没有。)它上面有签名证书(一个通过IIS管理器创建)刚刚得到了可怕的'无法验证第一个证书错误!
这似乎是因为IISManager为此目的创建的证书指定了一些'密钥用法'扩展; ' Key Encipherment'和'数据加密'。
事实证明,当openssl遇到指定'密钥用法' 但未能指定' certSign'使用然后openssl代码将该证书折扣为可能的CA证书,即使它已被正确提供给openssl代码(意味着它无法针对所述缺席CA验证证书!)。
解决方案如上所述,即使用正确的密钥用法创建自己的证书(或没有密钥用法扩展!)
我还认为我应该提供一种创建自签名证书的替代方法,如果你在windows中登陆,openssl客户会很满意。
首先从here
下载powershell脚本在powershell控制台(管理)中,从包含下载脚本的文件夹中执行以下命令
New-SelfsignedCertificateEx -StoreLocation "LocalMachine" -KeyUsage "DigitalSignature,KeyEncipherment,KeyCertSign" -Subject "CN=<HOST_NAME_TO_USE>" -FriendlyName "<HOST_NAME_TO_USE>" -SignatureAlgorithm sha256 -SubjectAlternativeName "<HOST_NAME_TO_USE>","anotherhost.org","someotherdomain.com"
执行上述命令后,您的LocalMachine \ Personal Certificates存储将包含一个自签名证书,IIS可以使用该证书进行SSL通信。 (请注意,您可能还需要将此证书复制到其中一个受信任的根存储中,以保证该证书在该计算机上受信任)