现在的位置: 首页 > 综合 > 正文

OpenSSL编程指引,第一部分

2018年03月15日 ⁄ 综合 ⁄ 共 1831字 ⁄ 字号 评论关闭
 in

Do you have a burning need to build a simple web client and server pair? Here's why OpenSSL is for you.

最快和最简单的创建一个安全的基于TCP协议的网络应用程序是使用SSL。如果你熟悉C语言,你最好选择OpenSSL。OpenSSL是Eric Young 的SSLeay包的一个免费实现。遗憾的是,与OpenSSL发布的文档和示例代码很少。在他们那里,手册页面很好,但是他们缺少大图,因此手册只是一个参考,而不是指南。

OpenSSL API是庞大何复杂的,因此我们并不想尝试在这提供所有内容。目标是教会你足以从手册页面有效的工作。这篇文章,第一部分,我们构建一个示范OpenSSL功能的简单的web客户端和服务器。在第二部分,我们将引进高级功能,例如会话恢复和客户端验证。

我假定你已经熟悉SSL和HTTP,至少在概念层。如果不是,一个开始的好地方是RFCs(参见引用)。

因为空间的原因,这篇文章仅包含源代码的摘录。完整的源码在作者的网站:http://www.rtfm.com/openssl-examples/


程序

我们的客户端是一个简单的HTTPS客户端。它初始化一个SSL连接到服务器,然后通过那个连接来传输HTTP请求。再然后它等待服务器响应并把他们打印在屏幕上。这是像fetch和cURL程序功能的最简化的版本。

服务器程序是简单的HTTPS服务器。它等待客户端的TCP连接。当他收到一个的话它产生一个SSL连接。一旦连接产生,它从客户端读取HTTP请求。然后它传输HTTP响应给客户端。一旦响应传输完毕,它关闭连接。

我们的第一个任务是设置一个上下文对象(SSL_CTX)。这个上下文对象接下来用来创建每一个SSL连接的新连接对象。这些连接对象用来SSL握手,读写数据。

这有两个好处。首先,连接对象允许许多结构体只要被初始化一次,来提高性能。在大多数应用程序中,每个SSL连接使用相同的秘钥材料,认证(CA)列表,等等。而不是为每隔连接都重新加载这些材料,我们仅仅在程序启动的时候把他们加载到上下文对象中。当我们希望创建一个新连接的时候,我们可以简单的吧连接指向上下文对象。第二个好处是一个单独的上下文对象允许多个SSL连接共享数据,例如用来恢复会话的会话缓存。上下文初始化有四个主任务组成,都由_ctx()函数初始化,在列表1中显示。

列表1.初始化_ctx()

在我们可以使用OpenSSL之前,SSL库必须先初始化。这由SSL_Library_init()完成,这主要加载OpenSSL将要使用的算法。如果我们想报告错误,我们也需要使用SSL_load_error_strings()来加载错误字符。否则,我们不能映射OpenSSL错误为字符串。

我们也需要对象用作错误打印上下文。OpenSSL使用一个抽象的叫做BIO的对象来输入和输出。这允许编程人员简单的使用不同的BIO对象来为不同的IO通道(sockets,终端,内存缓存,等等)使用相同的函数。现在我们创建附加在stderr的BIO对象来打印错误。

如果你写一个的服务器或可以执行客户端验证的客户端,你需要加载你自己的公/私秘钥对以及相关的证书。证书在内部存储并使用SSL_CTX_use_certificate_chain_file()加载CA证书链的形式。SSL_CTX_use_PrivateKey_file()
用来加载私钥。由于安全的原因,私钥通常用一个密码加密。如果这样,密码回调函数(使用SSL_CTX_set_default_passwd_cb()设置)被调用来获取密码。

如果你准备验证你连接的主机,OpenSSL需要知道你信任什么CA。调用SSL_CTX_load_verify_locations()来加载CA。

为了好的安全性,SSL需要一个强健随机数源。一般,应用程序有责任提供随机数发生器的材料。然而,如果可用的话,OpenSSL自动使用 /dev/urandom来初始化随机数发生器。由于 /dev/urandom在Linux上是标准,我们不需要为它做任何额外的事,这很方便。因为收集随机数是麻烦并且容易糟糕的。注意如果你不在Linux系统上,你可能由于随机数发生器没有初始化而在某些情况下出错。OpenSSL的rand手册页提供了更多信息。

抱歉!评论已关闭.