SSLStream示例 - 如何获取有效的证书?

Kev*_*son 24 c# ssl certificate

我使用的是从MSDN的SSLStream例子在这里.客户端代码"似乎"工作正常,因为我可以连接到谷歌,它至少得到过去的身份验证,但服务器没有.

从msdn页面的评论中,我使用此页面上的过程生成我自己的私钥,但它不起作用.我得到一个例外,System.NotSupportedException: The server mode SSL must use a certificate with the associated private key. 所以我很确定我做的事情是错的.

所以我的问题很简单:如何从msdn获取/生成适用于我自己的小示例程序的密钥?它可以是自签名的,但是我对SSL来说太新了,甚至不知道我到底需要什么.除了为本地服务器指定自己的证书之外,我想要做的就是运行as-given示例.如果我只是想在他们两个之间进行通信,那么知道我必须在我的第二台机器上安装什么是很好的(所以它不是100%本地主机的例子).

我个人认为这是示例文档中的一个缺陷.它应该说"要运行它,你需要做A,B,C等",但事实并非如此.

Tun*_*ung 46

即使使用自签名证书,您也可以使用该示例.我已经从你正在使用的makecert教程中提取了一些命令,只做了一些修改:

makecert -sv RootCATest.pvk -r -n "CN=FakeServerName" RootCATest.cer
makecert -ic RootCATest.cer -iv RootCATest.pvk -n "CN=FakeServerName" -sv  TempCert.pvk -pe -sky exchange TempCert.cer
cert2spc TempCert.cer TempCert.spc
pvkimprt -pfx TempCert.spc TempCert.pvk
Run Code Online (Sandbox Code Playgroud)

makecert并且cert2psc可以在您的Microsoft SDKs\Window\v7.0A\Bin文件夹中找到.该pvkImport.exe安装程序可以下载这里(由@Jospeph和VirusTotal提供的验证).以前这可以从Microsoft站点下载,但他们已经将其删除.另外,@ Dweeberly向我们指出了一个新的微软提供的替代品pvk2pfx.

对于下一步,请确保在pvkimprt的对话框出现时选择导出私钥:

pvkimprt -pfx TempCert.spc TempCert.pvk
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

pvkimprt当您选择包含私钥时,将提示您输入密码.将生成的.pfx文件导入服务器计算机的个人存储区时,需要稍后提供此密码

在此输入图像描述

接下来,将RootCATest.cer导入到Computer商店的受信任的根证书颁发机构(在服务器和客户端上).请注意,证书颁发给FakeServerName.这必须与SslTcpClient期望的服务器名称匹配:sslStream.AuthenticateAsClient(serverName),其中serverName是传递给SslTcpClient.exe的第二个参数的值.

当您的客户端连接时,服务器会提供一个证书,告诉客户端"我是FakeServerName".如果客户端计算机信任颁发证书的CA,则客户端将接受此声明,这通过将RootCATest.cer导入客户端的受信任的根证书颁发机构来实现.

最后,您需要将服务器将要使用的私钥导入服务器计算机的个人存储中. 这一步很重要,因为它解决了问题The server mode SSL must use a certificate with the associated private key..这是通过导入.pfx先前生成的文件来实现的.确保将文件类型过滤器更改为"所有文件",以便您可以看到生成的.pfx文件:

在此输入图像描述

MSDN提供的示例代码使用端口443(这是标准的ssl端口).自从我创建了控制台应用程序以来,我将示例类使用的端口更改为8080:

SslTcpServer:

TcpListener listener = new TcpListener(IPAddress.Any, 8080);
Run Code Online (Sandbox Code Playgroud)

SslTcpClient:

TcpClient client = new TcpClient(machineName, 8080);
Run Code Online (Sandbox Code Playgroud)

这是输出:

在此输入图像描述

你会像这样启动你的服务器:

SslTcpServer.exe TempCert.cer 
Run Code Online (Sandbox Code Playgroud)

从客户端,你会这样连接:

SslTcpClient.exe <ip to your server> FakeServerName
Run Code Online (Sandbox Code Playgroud)


avs*_*099 9

使用此命令生成证书:

makecert -r -pe -n "CN=localhost" -m 12 -sky CertSubject -ss my serverCert.cer
Run Code Online (Sandbox Code Playgroud)

然后从客户端连接到这样的服务器(假设我们使用你提到的MSDN示例):

SslTcpClient.RunClient ("localhost", "CertSubject");
Run Code Online (Sandbox Code Playgroud)

您将在ValidateServerCertificate()调用中获得验证错误 - 但这是预期的 - 您使用的是自签名证书.只要在那里回归真实.

更新:

我不同意董建议将自签名证书添加到客户的受信任的根证书颁发机构的建议.我认为如果您计划分发/支持您的软件,它可能会在以后引发问题.例如,客户端可能会重新安装Windows,或者将他的个人资料移动到另一台PC,或者其他什么 - 并且了解为什么你的软件突然停止工作会很痛苦(再次,我说的是长期 - 从现在起一两年,当时你完全忘记了这个小小的"诡计").

相反,我宁愿建议将您的证书"硬编码"(通过比较主题和指纹)到客户端的逻辑中,如下所示:

X509Certificate2 certificate = (X509Certificate2)cert;
if (certificate.Subject.StartsWith("CN=FAKE_SERVER_WHATEVER") &&
    !string.IsNullOrEmpty(certificate.Thumbprint) &&
    certificate.Thumbprint.ToLower() == "11c4446c572a9918ced3618728b91b3a07982787")
{
     return true;
}
return false;
Run Code Online (Sandbox Code Playgroud)


Jos*_*eph 5

由于Microsoft的 下载链接pvkimprt已断开,并且我是OpenSSL的粉丝,因此我在OpenSSL中保留了两种解决方案。

变量#1-自签名证书

首先,您需要下载OpenSSL和此配置文件。@Tung说您可以使用完全自签名的证书。将下载的配置文件复制到将运行OpenSSL命令的文件夹中。

让我们生成证书颁发机构的私钥和证书:

openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -out ssl-cacert.pem -keyout ssl-cakey.pem -outform PEM
Run Code Online (Sandbox Code Playgroud)

*使用-nodes参数可以省略密码,但是出于安全考虑,我个人不建议这样做。

如果要检查CA证书的信息,请执行以下命令:

openssl x509 -purpose -in ssl-cacert.pem -inform PEM
Run Code Online (Sandbox Code Playgroud)

让我们创建的证书请求,通用名称必须与机器的名称进行设置:

openssl req -config openssl.cnf -newkey rsa:2048 -keyout ssl-serverkey.pem -sha256 -out ssl-server.csr -outform PEM
Run Code Online (Sandbox Code Playgroud)

*与-nodes参数相同的注释。

如果要检查证书请求信息,请执行以下命令:

openssl req -text -noout -verify -in ssl-server.csr
Run Code Online (Sandbox Code Playgroud)

使用生成的CA证书签署证书请求:

openssl x509 -req -days 365 -CA ssl-cacert.pem -CAkey ssl-cakey.pem -CAcreateserial -in ssl-server.csr -out ssl-server-certificate.pem
Run Code Online (Sandbox Code Playgroud)

让我们以PFX格式制作自签名证书:

openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-server-certificate.pem -certfile ssl-cacert.pem -name "SSL Self Signed Certificate"
Run Code Online (Sandbox Code Playgroud)

现在,您应该导入.pfx证书。

  1. 双击ssl-certificate.pfx文件。
  2. 选择“本地计算机”选项,然后单击下一步。
  3. 输入密码,然后选中“将此密钥标记为可导出”复选框
  4. 选择单选按钮“将所有证书放置在以下存储中”
  5. 选择个人商店,然后单击下一步。

使用此步骤必须起作用。

变量#2-生成CA证书和服务器证书

我个人比第一个更喜欢此解决方案,因为只有我必须将Root CA证书分发给客户端。

首先下载配置文件。

我们将生成具有相应私钥的根CA证书:

openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -keyout ssl-cakey.pem -out ssl-cacert.pem -outform PEM
Run Code Online (Sandbox Code Playgroud)

让我们检查证书属性:

openssl x509 -purpose -in ssl-cacert.pem -inform PEM
Run Code Online (Sandbox Code Playgroud)

必须显示的信息应如下所示:

Certificate purposes:
SSL client : No
SSL client CA : Yes
SSL server : No
SSL server CA : Yes
Netscape SSL server : No
Netscape SSL server CA : Yes
S/MIME signing : No
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : Yes
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
-----BEGIN CERTIFICATE-----
MIIGLjCCBBagAwIBAgIJANCzs7UBFJMpMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
...
im1yDnB5nPwkPwZ9eRmlzIc6OaLZcfbFfSeSw8/ipKZcEJ1u+EFrB0JhuSbeLXtQ
N/8=
-----END CERTIFICATE-----
Run Code Online (Sandbox Code Playgroud)

使用以下命令创建证书请求:

openssl req -config openssl.cnf -newkey rsa:2048 -sha256 -keyout ssl-serverkey.pem -out ssl-servercert.csr -outform PEM
Run Code Online (Sandbox Code Playgroud)

用服务器的机器名设置公用名非常重要。

验证此证书请求的信息:

openssl req -text -noout -verify -in ssl-servercert.csr
Run Code Online (Sandbox Code Playgroud)

显示的信息必须具有以下格式,请检查“主题”部分中的“ CN”字段是否是服务器计算机的名称。

verify OK
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=US, ST=..., L=..., O=..., OU=..., CN=SERVERNAME
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:aa:92:bd:87:75:18:6c:c0:23:3f:0b:5a:46:1a:
                    ...
                    fe:13
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Key Identifier:
                7E:7D:79:F4:CD:71:0E:90:3A:9A:F8:3F:83:7D:89:90:4D:D4:F0:12
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment, Data Encipherment
    Signature Algorithm: sha256WithRSAEncryption
         34:e1:b4:db:b2:87:cc:11:3e:85:3c:ed:ac:8d:d9:43:ae:b0:
         ...
         56:84:29:f9
Run Code Online (Sandbox Code Playgroud)

创建证书文件夹:

mkdir certificates
Run Code Online (Sandbox Code Playgroud)

创建数据库索引文件:

Windows: type NUL > index.txt
Unix: touch index.txt

创建存储当前序列号的serial.txt文件:

echo '01' > serial.txt
Run Code Online (Sandbox Code Playgroud)

使用命令创建用于签署证书请求的服务器证书,为期两年。根据是否使用了-nodes参数,系统将提示您输入CA证书的密码

openssl ca -config openssl.cnf -days 730 -policy signing_policy -extensions v3_req -out ssl-servercert.pem -infiles ssl-servercert.csr
Run Code Online (Sandbox Code Playgroud)

然后显示以下格式的文本:

Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :ASN.1 12:'...'
localityName          :ASN.1 12:'...'
organizationName      :ASN.1 12:'...'
organizationalUnitName:ASN.1 12:'...'
commonName            :ASN.1 12:'SERVERNAME'
Certificate is to be certified until Jul  4 23:26:59 2018 GMT (730 days)
Sign the certificate? [y/n]: 
Run Code Online (Sandbox Code Playgroud)

选择y并将提示以下文本,再选择y一次:

1 out of 1 certificate requests certified, commit? [y/n]
Run Code Online (Sandbox Code Playgroud)

将生成的证书导出为PFX格式:

openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-servercert.pem -name "SSL Signed Certificate"
Run Code Online (Sandbox Code Playgroud)

您将需要执行以下步骤来毫无问题地启用SSL:

在服务器计算机上:

  • 在“信任的根证书颁发机构”商店上,选择“计算机帐户”,导入根CA证书(ssl-cacert.pem文件)。
  • 在“个人计算机”上,选择“计算机帐户”,导入SSL的服务器证书(ssl-certificate.pfx文件)。

在客户端计算机上:

  • 在每台客户端计算机上,您需要在受信任的根证书颁发机构存储中选择计算机帐户,导入根CA证书(ssl-cacert.pem文件)。

随时进行任何更改或建议。