如何验证自签名证书

9
我会清楚地向您提出问题,以便您可以回答我。
我有一个客户端-服务器(套接字)连接,我使用SslStream进行了安全保护。使用ssl使我确信我的客户端只会连接到我的服务器。
为了做到这一点,我必须在客户端中添加一个函数来验证服务器证书,并确保服务器是真实的(我的服务器)。
但我真的不知道如何验证自签名证书,希望得到您的帮助。
谢谢,提前致谢。

1
这将对您有所帮助:https://dev59.com/jXRB5IYBdhLWcg3wv5o_ - user1678541
1
我认为这个StackOverflow的问题会对你有所帮助:https://dev59.com/jXRB5IYBdhLWcg3wv5o_ - user1678541
我不想添加异常并继续连接!因为我实现SslStream的原因是我担心中间人攻击,所以我不能简单地忽略或添加异常来继续连接。 - Daniel Eugen
我想要验证这个服务器是100%我的真实服务器,而不是任何伪造的服务器或第三方。另外,如何确保我发布给客户端的certification.cer文件没有被修改或替换。 - Daniel Eugen
好的,现在我明白了你的问题 :-? 我会为你做更多的研究... - user1678541
抱歉,我不明白你的意思。我仍然遇到与我在之前两条评论中提到的相同的问题。 - Daniel Eugen
1个回答

12
假设证书不是自签名的 - 而是由可信的证书颁发机构签名。它能够工作的原因是因为你的客户端设备 - Windows、Mac、Linux、iPhone、Android设备已经拥有所有知名证书颁发机构的证书。当你建立连接时,操作系统会为你完成这项工作。它确保在连接期间发送给客户端的证书由一个知名的证书颁发机构签名。然而,这能够奏效的唯一原因是客户端已经拥有所有知名证书颁发机构的证书。
如果你选择使用自签名证书 - 或者由自签名证书颁发机构签名的证书 - 你需要自己来完成这项工作,而不是操作系统。不过,任务基本相同 - 你需要验证在连接期间发送给客户端的证书是否与预期的相匹配。你需要使用与签名证书相同的策略 - 客户端必须预先安装预期的证书(或证书链)。
以某种方式,你需要确保你的客户端已经拥有自签名证书。具体来说,是证书中的所有公共信息。客户端将没有私钥 - 因为私钥是...私有的。然后,你可以向你的应用程序添加代码来验证在连接期间发送的证书的哈希值是否与预先安装的证书的哈希值相匹配。
我注意到你之前已经问过类似的问题,也许你已经知道了所有这些。以下是一个额外的要点:
只要你保持自签名证书的私钥绝对安全,就没有任何人可以伪造你的自签名证书。这根本做不到。如果有人尝试这样做,他们将不得不生成一个新的私钥,它将与你的私钥不匹配 - 因为他们不知道你的私钥在哪里,而你已经将其保护好了。
然后一切都会崩溃。如果他们拥有不同的私钥,他们将需要一个不同的公钥。这意味着他们将拥有一个不同的证书哈希值。因此,当他们试图使用错误的公钥和哈希值进入时,你的应用程序已经知道正确的公钥和哈希值(如上所述),因此将拒绝连接。这是你必须在你的应用程序中完成的部分。如果他们尝试使用您的公钥和哈希,但使用不同的私钥,SSL将不允许他们建立连接。

1
那你能告诉我如何获取便宜的SSL证书吗?Go Daddy每年12美元的SSL认证是否好用?另外,我该如何生成CSR,我完全不知道。 - Daniel Eugen
3
抱歉,我仍在使用自签名证书,所以无法帮助你。我认为这些问题之前已经在该网站上被问过了 - 搜索是你的好朋友 :) - Guido Simone
感谢您的撰写。这篇文章解释了中间人攻击的原理,如果您在代码中没有验证证书,那么就可以通过自签名证书来实现攻击,并且为什么使用CA,您不必在代码中进行验证。太棒了,正是我正在寻找的! :) - Mausimo
非常好的答案,我一直在寻找一个能够做到这个的代码,但是我找不到,你能提供一个C#代码吗? - Medo Elkamaly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接