密码学专题 OpenSSL中SSL相关指令

再谈SSL和OpenSSL

  • 由于SSL协议已经是密码学和PKI技术中非常具体的一个应用协议,为了实现它,OpenSSL在密码学基础应用和PKI技术的基础实现上做了大量的工作,才逐渐形成和奠定了OpenSSL在密码学应用和PKI技术开发中的重要基础软件包地位。
  • OpenSSL涉及到SSL协议的实现、协议的应用和协议的开发调试等多个方面。
  • 本章将主要从应用层面上来对SSL协议进行阐述,这仅是OpenSSL提供的SSL支持的一部分内容,OpenSSL还提供了基于SSL开发API等更多具有重要价值的资料,但并未涉及。
  • OpenSSL提供了四个直接的SSL相关指令:s_client,s_server,s_time和sess_id,这些指令可以模拟SSL客户端和服务器端的多种动作和环境,用于测试和分析现有的SSL服务器或者客户端的运行状况,也可以将这些源代码作为实现SSL客户端或者服务器的参考。

用s_client指令模拟SSL客户端

功能概述和指令格式

  • s_client指令模拟了一个通用的SSL/TLS客户端。事实上,为了调试的目的,它比一般的SSL客户端实现复杂得多。你可以用s_client连接各种SSL服务器,如果你要连接一个HTTPS服务器(HTTS服务端口是443),输入下面的口令就可以:

  •  一旦s_client和某个SSL服务器的连接建立成功,那么服务器所有传送过来的信息都会被显示出来,而客户端的所有键盘输入也会被发送给服务器。
  • 下面通过对s_client指令各个参数的介绍来全面了解该指令的功能。
  • 首先看看s_client指令的格式:

  • 服务地址选项connect,host和port作为一个SSL模拟客户端,要运行的时候,首先当然需要指定SSL服务器的地址和服务端口。
  • connect选项指定了连接的主机地址和服务端口,其参数形式如下

  • 其中,host可以为IP地址,也可以为URL;
  • port为服务端口。事实上,你还可以使用两个很少使用的host和port选项来分别指定服务地址和服务端口,如下面的指令: 

  •  如果上述选项都没有使用,那么默认建立的连接为本地主机的4433端口。

客户端证书选项cert和key

  • cert选项指定客户端要使用的证书文件,该文件包含的证书仅在SSL服务器明确提出要求验证客户端证书的时候会被使用,否则该证书没有任何用处,cert选项也完全可以省略。
  • key选项则指定了客户端证书相应的私钥文件,如果使用了cert选项而没有使用该选项,那么指令会试图从cert指定的证书存储文件中读取私钥。当服务器要求进行客户端证书验证的时候,最常见到的错误就是声称客户端没有用户证书或者说提供的证书列表文件是空的(当然,你很有信心,你提供的证书文件绝对是包含一个证书的)。
  • 这种情况出现的原因,一般是因为服务器在要求客户端证书验证的时候发送过来的信任CA证书列表里面不包含签发你所提供的客户证书的CA证书。
  • 使用s_client指令,你可以查看到SSL服务器支持的CA列表。不过,有些SSL服务器只会在客户端访问某些页面的时候才要求进行客户端证书验证,这时候,为了看到其支持的CA证书列表,可以使用prexit选项将SSL连接过程中的所有信息打印处理。

验证服务器选项verify,CApath,CAfile,crl_check和crl_check_all

  • SSL支持双向的证书验证,也就是说,不仅仅服务器可以验证客户端的身份,客户端也可以验证服务器的身份。事实上,在目前的运用中,更常见的是客户端对服务器身份的验证。
  • 使用verify选项后,将启动SSL模拟客户端对SSL服务器证书的验证过程,同时,verify的参数设定了证书验证的深度,超过此深度,即视为证书验证失败。所谓证书验证深度,就是证书链(这里指服务器证书的证书链)的长度,即从根CA到服务器证书的层数,如果签发服务器证书的CA本身就是根CA,那么证书链长度就为1。
  • 需要注意的是,由于s_client仅仅是一个SSL客户端模拟程序,为了能充分显示出SSL连接过程中所有可能出现的问题,当验证服务器证书的过程中碰到错误或者应当视为验证失败的情况下,s_client程序也不会中断连接,而是会继续工作下去,当然,它会将所有错误信息忠实地输出来。所以,s_client程序永远不会因为验证服务器证书失败而终止运行。
  • CApath选项指定了存放用于验证服务器证书时使用的候选信任CA证书标准目录。在需要建立客户端的证书链时,该目录存放的证书也可能被使用。
  • CAfile选项则指定了一个存放一系列信任CA证书的文件,这些证书在验证服务器证书的时候需要使用。此外,当需要建立客户端的证书链时,这个文件中存放的CA证书也可能被使用。
  • crl_check选项告诉指令要同时检查服务证书在CRL列表中的状态
  • crl_check_al则告诉指令要检查整个服务器证书链中每一个证书在CRL列表中的状态。
  • CRL由cert指令指定的文件输入。

显示信息和状态选项showcerts,prexit,state,msg,debug和quiet

  • 默认情况下,s_client指令仅输出服务器的证书,如果使用了showcerts选项,则将显示服务器的整个证书链。在你验证服务器证书碰到问题时,可以使用该选项来诊断是否是证书原因。
  • 使用prexit选项后,无论SSL连接是否建立成功,当程序退出时都会试图输出所有会话(Sesion)信息。而一般情况下,仅在连接建立成功的时候,s_client选项才会输出会话信息。在以下几种SSL连接曾经成功建立的情况下,prexit选项对诊断SSL连接状态非常有用:
    • 1  使用的加密算法需要重新协商;
    • 2  因为需要对客户端证书进行验证导致SSL连接建立失败;
    • 3  在访问特定URL的时候要求进行客户端证书验证导致连接建立失败。
  • 当然,prexit选项输出的信息有时候不一定非常准确,因为有时候SSL连接可能从来就没有成功建立过,这时候输出的会话信息自然就没有任何意义。
  • state选项告诉指令输出SSL连接会话(Sesion)状态。
  • msg选项告诉指令以十六进制编码的格式输出所有协议相关的信息。
  • debug选项告诉指令输出所有的调试信息,并将所有的通信数据以十六进制编码的格式输出。
  • quiet选项告诉指令不要输出所有会话和证书信息,同时,该选项会默认打开ign_eof这个选项。

socket连接方式选项nbio_test和nbio

  • nbio_test选项告诉指令对非阻塞SSL通信socket进行更多的测试检查。
  • nbio选项告诉指令使用非阻塞socket进行SSL通信。

连接动作选项pause,reconnect,starttls和ign_eof

  • 使用pause选项后,指令在每次读或者写操作之后都会暂停一秒钟。
  • reconnect选项主要用于测试服务器会话缓存功能是否有效,使用该指令后,s_client会使用同一个会话(Sesion)反复连接相同的SSL服务器5次。有些应用协议支持TLS协议,但是必须在建立协议连接之后输入一个STARTTLS指令才能开始建立TLS连接的动作,s_client指令为了支持这种协议形式,增加了startls选项。
  • startls选项的参数是要建立连接的协议代码,目前仅支持“smth”协议,相信以后会慢慢完善和增加的(最新的版本已经增加了pop3协议)。
  • ign_eof选项告诉指令当输入文件到达文件尾(遇到文件结束符)时保持连接。如果不启用ign_eof选项(或者quiet选项),s_client指令跟服务器的连接建立后就处于交换模式,这时候还可以输入几个简单的指令来调整连接的状态,目前支持的指令包括:
    • 1  R,会话重新协商,即在行开始第一个字母输入“R”的时候,SSL当前的会话进行重新协商,采用新的会话;
    • 2  Q,断开连接,即在行开始第一个字母输入“Q”的时候,SSL当前连接立即断开,结束s_client指令。
  • 事实上,当输入到达文件尾(文件结束符)的时候,一样会断开连接。

 协议版本选项ssl2,ssl3,tls1,no_ssl2,no_ssl3和no_tls1

  • 这些选项告诉指令选择用什么版本的协议建立SSL连接。默认的情况下,SSL客户端支持所有版本协议,包括SSL2.0,SSL3.0和TLS1.0,并自动选择协商合适的协议建立连接。但是有些SSL服务器的实现并不规范,所以不一定能支持所有协议,并且会要求一定要不支持某种协议(如TLS1.0)才能够建立连接。
  • 使用ssl2,ssl3或者tls1选项是告诉指令只使用指定的版本协议,放弃其他协议。如果这几个选项同时使用,那么只有最后一个选项才会有效。
  • no_ssl2,no_ssl3和no_tls1选项则告诉指令放弃某种指定的协议。

密码算法选项cipher和serverpref

  • SSL客户端和服务器建立连接的时候,需要协商一组密码算法,用户通信加密和数据完整性保证等,通常情况下,服务器会从客户端发送过来的所有支持的密码算法组中选择第一组(服务器当然也必须支持该组算法)作为双方通信使用的算法。
  • 有时候可能你希望使用某组特定的算法,这时候就可以使用cipher选项来指定。关于cipher参数的具体信息,请参考本书相关章节的内容。
  • serverpref选项仅对SSL2.0协议有效,它告诉指令使用SSL服务器指定的算法来建立连接。

其他选项bugs,crlf,rand和engine

  • SSL/TLS有几个众所周知的实现上的BUG,s_client指令提供bugs选项来适应存在这些BUG的服务器。
  • crlf选项把终端输入的换行回车符转化成/r/n发送给SSL服务器,某些服务器有这样的特殊需求。
  • rand选项指定了用于产生随机数种子的文件,这跟其他指令的同名选项是一样的,这里不再多作介绍。
  • engine选项则告诉指令使用指定的Engine设备,参数是Engine设备的ID号。 

例子 

SSL服务器性能测试指令s_time

功能概述和指令格式

  • OpenSSL提供了另外一个与s_client相似的SSL客户端模拟程序s_time,不同的是,该程序主要用来测试SSL服务器的性能。
  • s_time程序通过从服务器下载一个页面,通过测试其传输的数据和花费的时间来测试SSL服务器性能,其测试的项目包括:
    • 1   给定时间段内建立的连接数量;
    • 2   传输的数据量;
    • 3   计算每个连接平均花费时间。
  • 下面是s_time指令的选项和格式:

网页内容选项www

  • www选项的参数指定了要从SSL服务器上获取(GET动作)的网页名称,例如“default.asp”这样的网页文件名。如果该选项没有定义,那么s_time指令只是完成握手建立连接,但是不传输任何应用数据。

连接会话选项new和reuse

  • new选项告诉s_time指令每次建立新SSL连接的时候都使用新的会话(Sesion)ID。
  • reuse选项则告诉s_time指令每次建立新SSL连接的时候使用相同的会话(Sesion)ID。
  • 这可以用来测试SSL服务器的会话缓存功能的工作状态是否正常。如果上述两个选项都没有使用,那么指令会默认将两个选项都打开,并交替执行这两个选项定义的内容。也就是说在建立新SSL连接的时候,指令一会儿用新的会话ID,一会儿重用上次会话ID。

连接时间选项time

  • 选项time告诉指令统计在该选项参数指定的时间内(单位是秒)s_time和SSL服务器能够建立连接并从服务器传输指定数据(如果www指定了页面)的次数。当然,最后测试结果出来的时间不一定正好是指定的时间,因为指令必须在等待一个完整的连接动作完成后才能够结束并给出结果。 

例子

SSL客户端分析 

  • OpenSSL同样很负责任地提供了s_server指令,用于模拟一个通用的而且负责的SSL服务器,目的就是为了能够对SSL客户端进行测试。
  • s_server指令不仅仅模拟了一个完整通用的SSL服务器,并且还在此基础上模拟了一个Web服务器,提供Web服务。
  • 下面是s_server指令的选项和格式:

 监听端口选项accept

  • accept选项指定SSL服务端口,在默认的情况下指令将使用4433端口。

证书和私钥选项cert,key,dcert,dkey和nocert

  • cert选项指定服务器使用的证书。大部分服务器算法簇的运行需要数字证书,而且有些还需要特定类型公钥的证书。例如在DSS算法簇中就需要一个包含了DSS(DSA)密钥的证书。cert选项如果没有定义,默认情况下将使用server.pem文件中的证书。key选项指定存储私钥的文件,该私钥和cert选项指定的证书应该是相对应的,如果本选项没有出现,那么cert选项定义的证书文件会被认为同时也是存储私钥的文件。正如前面所说,在SSL协议的算法簇中,不同的算法可能需要不同密钥类型的证书来进行服务器验证。
  • 例如,RSA算法簇需要RSA密钥证书来完成SSL连接的建立,而DSA算法簇则需要DSA密钥证书来完成SSL连接的建立过程。所以,为了使得SSL服务器能够兼容各种不同客户端的需要,可能需要在服务器端提供不同类型的证书以备选用,这就是下面dcert和dkey选项出现的原因。
  • dcert和dkey这两个选项用于在cert跟key选项之外再指定一个附加的证书文件和私钥文件,它们的用法跟cert和key选项是相同的,不过,dcert和dkey选项没有默认值。因为我们的服务器需要支持不同的组合密码,而不同的组合密码需要不同的证书和私钥文件。
  • 不同的组合密码在这里主要是指组合密码里面的不对称加密算法不同。比如基于RSA的组合密码需要的是RSA的私钥文件和证书;而基于DSA算法的,则需要的是DSA的私钥文件和证书,使用这两个选项,就使得我们的服务器同时支持两种不同的组合密码成为可能。nocert选项告诉服务器不使用证书进行SSL连接的建立,这样的直接后果就是造成需要使用证书的SSL算法簇不能使用,即SSL服务器将仅支持匿名的DH算法进行SSL连接建立。不过,目前有些浏览器(如IE和Netscape)仅支持基于RSA算法证书的SSL算法簇,如果SSL服务器不支持RSA算法,则将导致SSL连接建立失败。

DH参数选项dhparam和no_dhe选项

  • dhparam指定一个DH参数文件。DH密码簇在使用的时候需要一组DH参数来产生私钥。如果没有指定DH参数文件,当使用DH算法的时候,那么服务器首先会尝试从服务器证书文件里面获得DH参数;
  • 如果证书文件里面没有DH参数,那么s_server指令程序代码中的一组固定DH参数将会被使用。
  • no_dhe选项告诉s_server指令禁止一切的DH参数的调用,此时,DH算法簇将不会在SSL连接中被使用。

证书验证选项verify,Verify,CApath和CAfile

  • 选项verify要求客户端发送证书进行验证,同时其参数设置了客户端证书链最大的验证深度。但是,对于客户端来说,这仅是一个可选的动作,客户端如果不发送证书给服务器进行验证,也可以顺利建立SSL连接。
  • 而如果使用Verify选项表示客户端必须发送一个证书进行验证,否则SSL握手将失败。
  • 选项CApath指定了服务器存放可信任证书文件的目录,这些证书文件在对客户端证书验证的时候需要使用,此外,在要求建立服务器证书链的时候,目录中的这些证书也有可能被使用。
  • 选项CAfile指定一个存储证书的文件,该文件包含了服务器信任的CA证书,跟CApath一样,这些证书在进行客户端证书验证的时候需要使用,在建立服务器证书链的时候也可能被使用。此外,客户端进行SSL握手要求客户端发送用户证书时,这些证书将作为服务器可接受的信任CA列表发送给客户端。
  • 如果服务器端发送一个空的信任CA列表给客户端(比如没有定义CAfile文件),虽然理论上应该是违反协议规定的,但很多SSL客户端认为这时候服务器能够接受任何CA签发的证书,这在调试程序的时候可能反而会有些帮助。

Web服务器模拟选项www,WWW和HTTP

  • 使用www选项后,当SSL客户端连接上SSL服务器的时候,将接收到服务器发回的一些状态信息。这些状态信息包括连接使用的算法和会话参数等,并且被格式化成HTML的格式,所以,经常可以被Web浏览器SSL客户端接受和解释。
  • 使用WWW选项服务器端将模拟一个简单的Web服务器。指令程序所在的目录将被解释成网页的当前目录。例如如果客户端的URL请求是htps://myhost/page.html,服务器将把./page.html发回给客户端。
  • HTTP选项跟WWW选项的功能基本上是一样的,唯一的区别是,使用HTTP选项后,当前目录中所有被请求的文件,都假定是符合HTTP格式的文件。而选用WWW选项则s_server在发送被请求的文件给客户端之前,会根据后缀名判断被发送的文件是普通文件还是HTTP文件,并告知客户端。
  • 如果上述三个选项都没有使用,当一个SSL客户端成功连接到服务器后,客户端所发送过来的任何数据都会在服务器端显示出来,服务器端任何键盘输入也都会被发送给客户端。此时,一些单个的特殊字符在指令行可以输入,以达到一些特殊的目的,支持的字符指令及其含义如表12-1所示。

其他选项context,no_tmp_rsa,id_prefix和hack

  • context选项用于设置SSL结构体的ID,可以设置为任何值,如果不设置,将使用默认值。
  • 某些算法簇会要求使用一个临时的RSA密钥,no_tmp_rsa选项将禁止临时RSA密钥的产生。
  • id_prefix选项指定SSL/TLS所有会话ID的前缀。这个功能在测试多个SSL服务器的时候会非常有用(比如通过SSL代理的方式),每个服务器都会产生特定范围的会话ID,方便识别和调试。
  • hack选项是为了兼容早期版本的Netscape浏览器,一般来说使用很少。 

例子

  • 下面的例子必须在s_server程序的目录下放一个server.pem的文件,文件应该存有一个服务器数字证书和其相应的私钥,否则将出错。
  • 该程序模拟了一个SSL服务器和Web服务器: 

SSL会话深入分析

  • 在使用s_client或者s_server指令的debug选项进行调试的时候,通常会看到其中包括一段诸如下面的内容:

  • 这就是SSL会话(Sesion)结构的PEM编码,你可能看不懂上述这些不知所云的PEM编码内容。但是,分析一个SSL连接中所有会话的实际内容对于我们分析SSL连接及调试程序都是非常有用的,所以OpenSSL提供了一个翻译工具,帮助我们读懂上面的内容。
  • 所以,上面的方法,就是获取编码SSL会话结构的一种途径和需要之一。

 功能概述和指令格式

  • OpenSSL提供的ses_id指令就是用于处理保存下来的SSL会话(Sesion)编码结构,根据指令选项要求打印出其中的信息。
  • ses_id一般作为一个调试工具使用,并需要用到SSL协议的相关知识,这听起来有些难度,不过,幸运的是,很少用户会用到这个指令。其指令格式为:

 输入和输出格式选项inform和outform

  • 跟其他指令一样,这两个选项分别指定了输入和输出格式,其中,outform指定的也是输出编码会话(Sesion)结构的格式,不会影响其他可读内容的输出格式。目前支持的格式包括DER和PEM,默认是PEM格式。
  • PEM格式的SSL会话包含在一个固定结构中,第一行和最后一行格式如下:

 输入和输出文件选项in和out

  • in和out选项指定了输入和输出文件名,输入文件一般存储的是一个编码SSL会话结构,输出文件则输出SSL会话信息(也包括SSL的编码会话结构)。默认情况下是标准输入和输出设备。

输出内容选项text,noout和cert

  • 选项text将告诉指令对SSL会话结构进行完全的明文解释,输出所有可能的内容,其输出的信息典型如下面所示:

  • 当SSL会话结构中包含证书时,cert选项告诉指令输出该证书结构,如果同时还使用text选项,那么将输出证书的可读形式。
  • 一般情况下,sess_id指令最后都会输出SSL会话的编码结构,使用noout选项后,将只输出text选项或者cert选项要求输出的内容,而不再输出SSL会话的编码结构。

其他选项context

  • context选项用来指定一个特殊的ID替换编码里面的ID作为输出的会话ID,这个ID可以为任意字符串。

 例子 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值