OpenSSL,公钥和私钥

时间:2011-03-21 19:15:07

标签: c security ssl openssl

我最近一直在用C语言试验OpenSSL API,我对一些设置功能以及整体公钥加密中的某些概念感到困惑。

总的来说,我理解公钥加密的工作原理。您有一个公共密钥,每个人都可以使用,然后服务器和客户端都有一个秘密的私钥,这是解密邮件所必需的。

但是,当你实际上需要一个公钥时,我有点困惑。例如,Web浏览器是否需要公钥?我想不会,因为在大多数用例中,只有服务器(不是客户端)才需要公钥。如果服务器和客户端都有公钥,那么使用哪一个?

令我感到困惑的是,OpenSSL API定义了一个函数SSL_CTX_use_PrivateKey_file(),但没有相应的SSL_CTX_use_PublicKey_file()。在我的实验中,我写了一个简单的Web客户端,它连接到https网站并下载文件。它工作正常,不需要公钥。我只是使用OpenSSL命令行工具创建了一个私钥,然后在我的程序中调用了SSL_CTX_use_PrivateKey_file()

但是,如果我正在编写服务器,而不是客户端,我不需要公钥吗?如果是这样,为什么我在OpenSSL API中看不到use_PublicKey_file之类的内容?

4 个答案:

答案 0 :(得分:1)

在TLS / SSL连接中,公钥作为用于对一方进行身份验证的证书的一部分提供 - 证书将标识与特定公钥绑定。服务器端始终提供证书(公钥),因为服务器端必须始终向客户端证明其身份。

客户端也可以提供证书,如果它想要证明其身份(并且它有合适的证书) - 在您的Web浏览器示例中,它通常 不提供客户端证书,但可以。有些网站确实使用客户端证书进行身份验证。

如果使用公钥,则必须使用相应的私钥 - 密钥成对出现。提供公钥的相应功能是SSL_CTX_use_certificate() - 公钥是证书的一部分。提供一个没有另一个是毫无意义的 - 在您的客户端示例中,您可以完全省略对SSL_CTX_use_PrivateKey_file()的调用。

答案 1 :(得分:0)

通常,私钥用于解密,公钥用于加密和验证。

我对OpenSSL C接口并不熟悉,但我的猜测是你实际上并没有对从文件中加载的密钥做任何事情。您正在使用的下载例程是下载Web服务器的证书,验证它是否针对已知的签名授权链,然后协商tls(共享密码)加密流。

换句话说,对于HTTPS,公钥加密仅用于您的计算机在流密码协商之前验证服务器的真实性。一旦完成,双方将拥有共享密钥,并且所有内容都使用常规加密进行加密。

TLS RFC包含所有血腥细节。

答案 2 :(得分:0)

密钥成对出现 - 对于每个公钥,都有相应的私钥,每个私钥都有一个相应的公钥。因此,谈论私钥或公钥是没有意义的 - 而是你需要指定你所谈论的关键词。

在“正常”(非客户端验证的)SSL连接中,有一个密钥对,即服务器的密钥对。服务器知道自己的私钥,客户端需要知道服务器的公钥,公钥通常以证书的形式出现,证书由某个证书颁发机构的私钥签名。因此,当客户端首次连接到服务器时,服务器所做的第一件事就是发送其公钥证书(因此客户端拥有它)。客户端使用CA的公钥(需要内置或预加载)对证书进行身份验证。然后客户端发出“秘密”(随机数)并使用服务器的公钥对其进行加密并将其发送到服务器可以用私钥解密它。然后,该秘密用于为用于进一步通信的对称密码设置密钥。

在经过身份验证的SSL连接中,客户端和服务器都具有私钥,并在建立安全连接之前在整个连接中提供其证书(带有相应的公钥)。

答案 3 :(得分:-1)

客户端通常不需要公钥。客户端将在握手期间生成随机公钥,以便服务器可以加密仅客户端可以解密的消息,但此公钥的生命周期与连接的生命周期相同。

作为客户端,为了获取服务器的公钥,您将使用证书SSL_CTX_use_certificate_file。证书包含公钥,通常由受信任的证书颁发者验证。只要您信任证书颁发者,这就保证了客户端服务器的真实性。 Web浏览器随附一组受信任的证书颁发者,因此可以验证他们将下载的证书。