SSL安全协议(中文版)_第1页
SSL安全协议(中文版)_第2页
SSL安全协议(中文版)_第3页
SSL安全协议(中文版)_第4页
SSL安全协议(中文版)_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/SSL协议Version3.03/4/96 翻译—隋立颖一本文件的地位本文件是一个Internet草案。Internet草案是Internet工程特遣组(ITEF)及其领域和工作组的工作文件.请注意,其他团体也可以发布Internet草案.Internet草案自公布之日起至多六个月内有效。它可以随时被修改、被替换,或被其他文件所覆盖。把Internet草案作为文献来引用,除说明是“正在进展中的工作”以外,是不合适的。要了解任何一个Internet的当前地位,请查阅如下网址:(美国东海岸),(欧洲),(美国东海岸)以及munnari。oz.au(环太平洋地区)。其中InternetDraftsShadowDirectories目录下的1id—abstract.txt列表可提供这方面的信息。二摘要本文制定了安全套接层协议第3。0版(SSL3.0)规范.SSL是一个提供Internet上的通信隐私性的安全协议.该协议允许客户端/服务器应用之间进行防窃听、消息篡改及消息伪造的安全的通讯。三简介制定SSL协议的初衷是为通讯双方提供安全可靠的通讯服务,协议包含两个层次:其较低的SSL记录层协议位于某一可靠的传输协议(例如TCP[TCP]协议)之上;SSL记录层协议用来对其上层的协议进行封装。握手协议就在这些被封装的上层协议之中,它允许客户端和服务器彼此认证对方;并且在应用协议发出或收到第一个数据之前协商加密算法和加密密钥。这样作的原因是保证了应用协议的独立性,使低级协议对高级协议是透明的。SSL协议提供的连接安全性具有以下三条属性连接是安全的。在初始化握手协议协商加密密钥之后传输的消息均为加密的消息.加密的算法为单钥加密算法(例如DES[DES],RC4[RC4]等)。对方的身份是可以通过非对称加密算法—即公钥加密算法(例如RSA[RSA],DSS[DSS]等)来验证.连接是可靠的。所传输的消息均包含一利用签名私钥加密的消息文摘(MAC),以保证消息的完整性。安全杂凑(hash)函数(例如SHA,MD5等)被用来产生消息文摘(MAC).四目标按它们的优先级,SSL协议3.0的目标是在通讯双方之间利用加密的SSL消息建立安全的连接。互操作性。通讯双方的程序是独立的,即一方可以在不知道对方程序编码的情况下利用SSL3.0成功的交换加密参数.注意:并不是所有的SSL的实例(甚至在同一应用程序内)都可以成功的连接.例如,如果服务器支持一特定的硬件令牌(token),而客户端不能访问此令牌,则连接不会成功。可扩展性。SSL寻求提供一种框架结构,在此框架结构中,在不对协议进行大的修改的情况下,新的公钥算法和单钥算法可以在必要时被加入.这样做还可以实现两个子目标避免产生新协议的需要,因而进一步避免了产生新的不足的可能性。避免了实现一完整的安全协议的需要.相对的有效性。加密操作,尤其是公钥加密,对CPU来说是一种很耗时的事,因此SSL协议引入一可选的对话缓存(CACHE)来减少从头开始的连接的数目。同时,它还注意减少网络的活动。五此文档的目的SSL协议版本3。0详细说明书的主要读者是要实现此协议的人和进行加密分析的人。此详细说明书主要是为这两类人而写的,所以它时刻注意反映这两类人的需要。因此在本详细说明书中(而不是写在附录中)以文本方式包含了许多与算法相关的数据结构和规则,使它们易于被访问.虽然本详细说明书包含了维护物理安全性所必须的策略,本详细说明书并不想提供关于服务和界面的定义.六描述语言(Presentationlanguage)本文档主要是描述外部表示(externalrepresentation)的数据的格式,所以用到了下列简单、基础而有点随意的定义的表示语法,这些语法在结构上来自不同的出处。虽然这些语法在结构上有点象程序设计语言C、在语法和目标上象XDR[XDR],但过分的强调这种类似是有害的。本描述语言的目的仅仅是描述SSL.6.1基本块长(Basicblocksize)所有的数据项的表示均是显式说明的,基本数据块的长度为一字节(也就是说8比特)多字节的数据项是由从上至下、从左至右的多个字节连接组成。从字节流的角度来看,一多字节的数据项(在本例中是一数字)是通过下述公式形成的:value=(byte[0]〈〈8*(n-1))|(byte[1]<<8*(n-2))|。。。|byte[n—1];这种字节的顺序关系是网络中常用的顺序关系即大endian格式.6。2杂项注释以“/*"开始,以“*/”结束。可选的部分是由将其包含进斜体的括号“[]”中而指定的。单字节的包含不可解释的数据的实体的类型为opaque6.3向量(Vectors)向量(一维数组)是一同类型的数据元素的流,向量的规模可以在编写文档时说明,也可以留至运行时才指明;不管在哪一种情况下,向量的规模(即大小)是由向量中字节的个数而不是向量中元素的个数决定的.说明一新类型T'是一固定长度的类型T的向量的语法为:TT'[n];在这里,T’在数据流中占n比特,其中n是T的所占字节数的倍数。向量中包含数据元素的个数没有包含在数据流之中。在下例中,Datum被定义为三个连续的协议无法解释的字节的向量;而Data被定义为三个连续的Datum,一共包含9个字节opaqueDatum[3];/*三个协议无法解释的字节*/DatumData[9];/*三个连续的包含三个字节的向量*/可变长向量可以通过指明合法长度的范围,即形如<最小长度..最大长度>的形式来定义,在编码时,在字节流中实际长度应在向量的内容之前,此实际长度是以数字的形式存储的,此数字应能表示此向量的最大长度(ceilinglength)。空向量指的是一实际长度为零的向量。TT'<floor..ceiling〉;在下例中,mandatory是一必须包含300到400字节的opaque类型数据的向量,它不能是空向量,其实际长度域占有两个字节,即uint16,足以表示400(见6。4节),而longer最多能表示800个字节,即400个uint16的数据元素,且〈请合法使用软件>可以是空向量。它的编码包含一两字节的实际长度域。opaquemandatory〈300.。400>;/*长度域为两个字节,不能为空向量*/uint16longer<0。.800〉;/*零至400个16比特的无符号整数*/6.4数字(Numbers)基本的数字的数据类型是无符号字节(uint8).其他所有的大的数字均是由6.1节中描述的固定长度的字节流连接而成,且它们均是无符号的。下列数字类型是预定义的:uint8uint16[2];uint8uint24[3];uint8uint32[4];uint8uint64[8];6.5枚举(Enumerate)另一类稀疏的数据类型是枚举(enum),枚举类型的数据的取值范围只能是在其定义是声明的值。每一次定义均定义了一不同的类型。只有相同类型的枚举数据才可以相互赋值和比较,枚举类型的每个枚举元素均必须象下例中所示的那样,被赋一个值。由于枚举类型这的元素是没有顺序的,所以它们可以取任意顺序的不同的值。enum{e1(v1),e2(v2),...,en(vn),[(n)]}Te;枚举类型的值在字节流中占据的空间的大小是其定义的取值范围中最大的可能值所占的空间大小。下列定义会使类型Color占有一个字节.enum{red(3),blue(5),white(7)}Color;你还可以通过指定一个无标签的值来强制枚举类型所占的字节数,这样就不需定义一冗余元素了。在下例中,类型Taste在字节流中占两个字节但只能在1,2或4中取值。enum{sweet(1),sour(2),bitter(4),(32000)}Taste;枚举类型的元素的名字只在定义的类型中是有效的。在第一个例子中,对类型Color中的第二个元素的完全限定引用为Color.blue。这样的限定当赋值的目标是被说明的时候时是可以忽略的。Colorcolor=Color。blue;/*重复说明,但是合法的*/Colorcolor=blue;/*正确,类型是隐含的*/对于元素的值不会转化为外部表示的枚举类型,元素的取值信息是可以省略的。enum{low,medium,high}Amount;6。6结构(Constructedtype)结构类型可以由基本的数据类型方便的建成,每一次说明均声明了一新的、唯一的类型,定义的语法类似于C语言中结构的定义。struct{T1f1;T2f2;.。.Tnfn;}[T];在一结构中的各域可以象枚举中引用元素时的语法一样用类型名加域名引用,例如T.f2引用的是上例中的第二个域,结构的定义可以嵌套。6.6.1变体结构(Variant)定义结构时可能根据环境的不同而有不同的变体,选择器必须为枚举类型的数据,以定义结构中可能的变体,且必须用case语句将select中声明的每个枚举元素不会起来。变体结构的结构体可以有一供其引用的标签.在运行时如何决定变体的机制并没有在描述语言中规定。struct{T1f1;T2f2;。.。Tnfn;select(E){casee1:Te1;casee2:Te2;.。..caseen:Ten;}[fv];}[Tv];例如:enum{apple,orange}VariantTag;struct{uint16number;opaquestring<0..10>;/*可变的长度*/}V1;struct{uint32number;opaquestring[10];/*固定的长度*/}V2;struct{select(VariantTag){/*变体的选择器是隐含的*/caseapple:V1;/*VariantBody的定义,标签=apple*/caseorange:V2;/*VariantBody的定义,标签=orange*/}variant_body;/*可选的变体标签*/}VariantRecord;变体结构可以通过在类型前指定选择器的值来限定(narrowed),例如:orangeVariantRecord是类型VariantRecord的一限定,它包含类型为V2的variant_body。6.7加密属性(Cryptographicattribute)数字签名、流加密、块加密和公钥加密这四项加密操作的加密属性分别为digitally-signed,stream—ciphered,block—ciphered和public-key-encrypted.对一个域进行何种加密操作是由在此域的类型说明前的合适的加密属性(关键字)决定的,加密的密钥是由当前对话状态字隐含给出的(见7.1节)。在数字签名中,输入为一单向哈希函数(one—wayhashfunction)。当用RSA算法进行签名时,用签名私钥对一36字节的结构进行签名,此36字节的结构是由两个哈希函数生成的,一个为SHA,另一个是MD5.当用DSS算法进行签名时,可以直接对由SHA哈希函数生成的20字节的结构进行签名。在流加密中,明文的长度与由密钥产生的密文的长度是相同的。此密钥是由伪随机数发生器生成的安全的密钥,是根据时间的变化而变化的。在块加密中,密文的每一块均被加密成一块密文。由于明文的长度并不是固定的,所以有可能在对明文(发出的数据)分块时产生一不满的块(块的长度通常为64比特),此时就需要将此不满的块的剩余部分填充数据,一般来说是填零.在公钥加密中,单向限门函数被用来加密要发出的数据,用一给定公钥加密的数据仅能由相应的私钥解出,同样用一给定私钥加密的数据仅能由相应的公钥解出。在下例中:stream—cipheredstruct{uint8field1;uint8field2;digitally-signedopaquehash[20];}UserType;哈希函数的结果做为签名算法的输入,整个结构UserType用流加密进行加密.6.8常量(Constant)有类型的常量可以通过在常量名前加上所希望的类型,并在常量名后给其赋上所期待的值来定义.未限定的类型(opaque,可变长向量,变体结构及带有opaque的结构)不能被赋值。多元素的结构和向量的所有域均应被赋值。例如:struct{uint8f1;uint8f2;}Example1;Example1ex1={1,4};/*令f1=1,f2=4*/七、SSL协议SSL是一层次化协议。在每一层,消息均可以包含描述长度、消息的描述及消息的内容的域.SSL在传输消息时,首先将消息分为其可处理的数据块,可以进行压缩,将其封装为一带消息验证(MAC)的包,随之进行加密并传输所得到的加密后的消息.在收到消息时,首先解密,然后验证、解压缩并重新组合得到原有的消息,将此消息发向较高的层次。7.1对话及连接状态SSL的对话是有状态的,是由SSL的握手协议来同步客户端和服务器的状态的,因而允许它们一致的操作而不管它们的协议状态是否是并行的。从逻辑上讲,状态被提到了两次,一次是当前的操作状态,而另一次是在握手协议中的未决状态。而且,还维持单独的读状态和写状态。当客户端或服务器收到changecipherspec消息时,它将未决读状态复制到当前读状态.当客户端或服务器发出changecipherspec消息时,它将未决写状态复制到当前写状态。当握手协商完毕时,客户端或服务器将彼此交换changecipherspec消息(见7.3节),这样它们就可以用新同意的cipherspec来进行通信了。SSL对话可以包含若干次安全连接,而且每一方均可以同时有多个对话.对话状态包含下列元素:对话标识一由服务器为标识当前活跃的对话或重新开始的对话而随机选取的字节流.对等证书对等方的X509。v3[X509]证书,状态的此元素可以为空。压缩方法在加密之前压缩数据所采用的算法。加密说明指出所采用的数据加密算法(如没有采用加密算法,采用DES等)和作消息文摘的算法(如MD5,SHA等),它还定义象hash_size一类的加密的属性(见附录A。7)主共享的秘密客户端和服务器所共享的48比特的共享的秘密.是否可以重开始一标识此对话是否可以用来初始化新的连接的标志。连接状态包含下列元素:客户端和服务器的随机数由客户端和服务器为建立一次连接而随机选取的一字节流.服务器的MAC写共享秘密服务器在对数据进行消息验证(MAC)操作时所使用的共享的秘密.客户端的MAC写共享秘密客户端在对数据进行消息验证(MAC)操作时所使用的共享的秘密。服务器的写密钥服务器在对数据进行加密时所使用的加密密钥,此密钥也是客户端进行解密时的解密密钥。客户端的写密钥客户端在对数据进行加密时所使用的加密密钥,此密钥也是服务器进行解密时的解密密钥。初始化向量当用CBC方式进行块加密时,对于每一密钥系统都将维护一初始化向量(IV)。此域的值是由SSL握手协议进行初始化的,为以后使用的方便此后的每一记录的最终的密文块被保存在记录的后面。序列号参与连接的每一方都为其发出的和收到的消息维护一独立的序列号。当一方发出或收到ChangeCipherspec消息时,其序列号置为零。序列号的类型为Unit64,所以序列号不能超过264-1。7.2记录层SSL记录层由更高的层次那里接收未加解释的任意长度的非空块。7。2.1打包记录层将信息块分裂为小于或等于214字节的SSLPlainText记录。客户端消息的界限并不反映至记录层中(也就是说,具有同样ContentType的多个客户消息可能会合并为一SSLPlaintext记录)。struct{uint8major,minor;}ProtocolVersion;enum{change_cipher_spec(20),alert(21),handshake(22),application_data(23),(255)}ContentType;struct{ContentTypetype;ProtocolVersionversion;uint16length;opaquefragment[SSLPlaintext.length];}SSLPlaintext;其中type指出采用打包的更高层次的协议.version协议的版本号。此文档所描述的是SSL版本3.0(见附录A.1。1).lengthSSLPlaintext的字节长度,此长度不应超过214fragment应用数据。此数据对由Type域中所指出的更高层次的协议是透明的,并被视为一独立的块。注意:不同的SSL记录层的CententType数据可以交叉存取,应用数据一般要比其他的ContentType数据要求更低级的传输过程。7.2。2记录的压缩和解压缩所有的记录均应用在当前的对话状态中定义的压缩算法进行压缩.一般地,此算法为当前活跃的压缩算法,但在初始化时它被定义成CompressionMethod。null。压缩算法将SSLPlaintext结构转换为SSLCompressed结构,当CipherSpec变换后,压缩函数将删除其状态信息。注意:CipherSpec是在7.1节中所描述的对话状态的一部分,对CipherSpec中各域的引用在本文档中是用表示语法来表达的。关于CipherSpec的更加详细的描述见附录A.7.压缩必须是无损压缩且对原文的长度的增加不超过1024比特.如果解压缩函数遇到一待解的超过214比特的SSLCompressed.fragment,它将产生一终止的decompression_failure报警(见7.4.2节)。struct{ContentTypetype;/*sameasSSLPlaintext。type*/ProtocolVersionversion;/*sameasSSLPlaintext。version*/uint16length;opaquefragment[SSLCompressed.length];}SSLCompressed;lengthSSLCompressed。fragment的长度(单位:字节)。长度不应超过214+1024.fragmentSSLPlaintext.fragment的压缩格式。注意:操作CompressionMethod.null是一标识性操作,没有任何一个域的值被改变(见附录A。4.1). 实现时请注意:解压缩函数的责任是保证消息不会造成内部的缓冲区溢出。7.2。3记录的有效负荷保护和加密说明(CipherSpec)所有的记录均用在当前的加密说明(CipherSpec)中定义的加密算法和消息验证(MAC)算法所保护,一般地,在SSL内部有一活跃的CipherSpec,但在初始化时,它的值为SSL_NULL_WITH_NULL_NULL,从值并不提供任何安全性.只有当握手结束后,参与双方共享一用于加密记录和计算消息验证码(MACs)的公共秘密。进行加密和消息验证(MAC)操作的技术有CipherSpec定义,并受CipherSpec。cipher_type的限制。加密和消息验证(MAC)函数将一SSLCompressed结构转换为一SSLCiphertext结构,解密函数作相反的过程。传输时将包含一序列号,这样当包丢失、被改变或包被重复收到时可以及时的发现。struct{ContentTypetype;ProtocolVersionversion;uint16length;select(CipherSpec.cipher_type){casestream:GenericStreamCipher;caseblock:GenericBlockCipher;}fragment;}SSLCiphertext;type类型域被指定为SSLCompressed。type。version版本域被指定为SSLCompressed。version。length指明随后的SSLCiphertext.fragment的长度(单位:字节)。长度不应超过214+2048。fragment包含消息验证码(MAC)的SSLCompressed.fragment加密后的形式。7.2。3.1Null或标准的流加密流加密(包含BulkCipherAlgorithm.null–见附录A.7)将SSLCompressed.fragment结构转换为SSLCiphertext.fragment流结构,或者反之,将SSLCiphertext。fragment结构转换为SSLCompressed.fragment流结构。stream-cipheredstruct{opaquecontent[SSLCompressed。length];opaqueMAC[CipherSpec.hash_size];}GenericStreamCipher;产生的消息验证码(MAC)形式为:hash(MAC_write_secret+pad_2+hash(MAC_write_secret+pad_1+seq_num+length+content));其中“+"表示将前后连接起来.pad_1字符0x36在MD5算法中重复48次或在SHA算法中重复40次。pad_2字符0x5c,与pad_1一样的重复。seq_num从消息的序列号。hash由cipher组合所决定的杂凑算法.请注意,消息验证码(MAC)在加密之前就计算出来了。流加密加密的是包含消息验证码(MAC)在内的整个块。对于不用同步向量的流加密方法(如RC4),在记录后边的流加密方法的状态被简单的用在随后的包中,若CipherSuite是SSL_NULL_WITH_NULL_NULL,且加密包含指定的操作(也就是说,数据还未被加密且消息验证码(MAC)的长度为零,标志着不使用消息验证码(MAC)),则SSLCiphertext的长度是SSLCompressed的长度与CipherSpec.hash_size的和。7。2.3.2密码分组链接(CBC)块加密对于块加密(象RC2或DES),加密和消息验证(MAC)函数将SSLCompressed.fragment结构转换成SSLCiphertext。fragment块结构.block-cipheredstruct{opaquecontent[SSLCompressed.length];opaqueMAC[CipherSpec.hash_size];uint8padding[GenericBlockCipher。padding_length];uint8padding_length;}GenericBlockCipher;消息验证(MAC)与7.2。3。1节中描述的一样。padding为了使明文的长度成为加密块长度的倍数而添加的随机字节。padding_length填料的长度必须比加密块的长度小且可以为零,填料的长度应使结构GenericBlockCipher的总长度是加密块长度的倍数被加密的数据长度(SSLCiphertext.length)应比SSLCompressed的长度,CipherSpec。hash_size和填料的长度的总和多一。注意:对于CBC块加密来说,其第一个记录的CBC块链的初始化向量(IV)是由握手协议提供的,随后记录的IV是前一记录的最后一密文块。7。3更改加密说明cipherspec的协议更改加密说明(cipherspec)的协议在加密策略中被用来通知参与各方这一改变。协议只包含一个在当前(不是未决的)CipherSpec下加密并压缩过的消息.此消息包含一个字节,其值为1。struct{enum{change_cipher_spec(1),(255)}type;}ChangeCipherSpec;更改cipherspec的消息可以由客户端或服务器发出来通知对方随后的记录将由刚协商好的CipherSpec和密钥来保护.收方收到此消息后,将读未决状态复制到当前读状态中。客户端在密钥交换握手和证书验证消息(如果有的话)之后发出更改cipherspec的消息,服务器则在成功的处理了客户端发来的密钥交换消息之后发出一更改cipherspec的消息。一意外的更改cipherspec消息应产生一unexpected_message报警(见7。4。2节)。当重新开始一原有的对话时,更改cipherspec消息应在问候消息(hellomessages)之后发出.7.4报警协议由SSL记录层所支持的一种媒体类型为报警类型,报警消息带有此消息的严重程度的编码和对此报警的描述。最严重一级的报警消息将立即终止连接,在这种情况下,本次对话的其他连接还可以继续进行,但对话标识符必须无效以防止此失败的对话重新建立新的连接。象其他的消息一样,报警消息是利用由当前连接状态所指出的算法加密和压缩的。enum{warning(1),fatal(2),(255)}AlertLevel;enum{close_notify(0),unexpected_message(10),bad_record_mac(20),decompression_failure(30),handshake_failure(40),no_certificate(41),bad_certificate(42),unsupported_certificate(43),certificate_revoked(44),certificate_expired(45),certificate_unknown(46),illegal_parameter(47)(255)}AlertDescription;struct{AlertLevellevel;AlertDescriptiondescription;}Alert;7.4.1关闭报警客户端和服务器为避免截断攻击必须共享连接已关闭这一信息,它们中的任一方均可以初始化关闭信息的交换.close_notify此消息通知收方发出者不会在此连接内再发任何消息,当一次对话中的所有连接都没有恰当的close_notify消息而终止时,此次对话是不能重新开始的。close_notify消息的严重程度是警告级的7.4.2错误报警在SSL握手协议中的错误处理是很简单的,当发现一个错误后,发现方将向对方发一消息。当传输或收到最严重一级的的报警消息时,连接双方均立即终止此连接。服务器和客户端均应忘记前一次对话的标识符、密钥及有关失败的连接的共享信息.SSL中定义了下列错误报警:unexpected_message收到一意外的消息,此报警通常是致命性错误的报警且不应在正常的连接中被观察到。bad_record_mac当收到一带有不正确的MAC的记录时,将返回此报警。此报警通常是致命性错误的报警.decompression_failure解密函数收到不合法的输入(如数据太长等),此报警通是致命性错误的报警.handshake_failure收到一handshake_failure报警消息表明发出者不能接受现有的选项所提供的安全参数的集合,此报警通常是致命性错误的报警。no_certificate当被要求给出证书而没有合法的证书时,将发出一no_certificate报警消息.bad_certificate当一证书被讹用、或者证书中不会的签名不能被正确的认证等时,发出此报警。unsupported_certificate一有不被支持的类型的证书(如包含了用户自定义的扩展).certificate_revoked一被其发出者取消的证书.certificate_expired一过期了的或不合法证书。certificate_unknown由一些不明的发出者发出的证书所引起的证书的不可接受性。illegal_parameter在握手中的一个域的值溢出或与其他域的值不一致,此报警是致命性错误的报警。7.5握手协议总揽对话状态的加密的参数是由SSL握手协议产生的,握手协议是在SSL记录层的顶部操作的。当一SSL客户和服务器首次开始通讯时,它们就协议版本、加密算法的选择、是否验证对方及公钥加密技术的应用进行协商以产生共享的秘密,这一处理是由握手协议完成的,可以总结如下:其中*表示不是必须发出的可选的或依赖于环境的消息客户端首先发出客户问候消息(clienthellomessage),服务器收到之后或者发出服务器问候消息(serverhellomessage),或者发生一终止性的错误然后此次连接将无法建立客户和服务器问候消息(clienthellomessage)被用来在客户端和服务器之间建立安全的性能的协商,客户和服务器的问候消息(clienthellomessage)将产生了下列属性:协议版本号、对话标识符、加密套接字及压缩方法,而且产生了两个随机数ClientHello。random和ServerHello.random并且相互交换.在问候消息之后,若要求验证身份,服务器将发出其证书,另外,如果需要的话(例如,如果他们的服务器没有证书,或者其证书仅用来进行签名),将发出一个serverkeyexchange消息。如果这个服务器已经被认证,而且被所选的密码组(cipherSUITE)所允许的话,它将向客户端请求证书。现在这个服务器将发出服务器问候结束消息(serverhellodonemessage),表明握手过程中的问候消息阶段已经结束。这个服务器接着将等候客户端的回答。如果服务器发出一个certificaterequest消息,客户端必须发出证书消息(certificatemessang),或者一个nocertificate报警。现在,客户端密钥交换消息(clientkeyexchangemessage)准备发送,而且消息的内容将取决于在客户端问候消息(clienthellomessage)和服务器问候消息(serverhellomessage)之间所选择的公钥算法。如果客户端已经发出了一个具备签名能力的证书,一个数字签名后的证书验证消息(certificateverifymessage)将被发送以确认此证书的合法性。就这一点而言,一个改变加密说明(changecipherspec)消息是被客户端发送的,而且客户端将未决的CipherSpec复制到当前CipherSpec。然后,客户端立即用协商的新的算法、密钥、和共享信息发出结束消息。服务器将发出其自己的改变cipherspec消息(changecipherspecmessage)作为回应,将未决(pending)cipherspec复制到当前CipherSpec,并用新的cipherspec发出其结束消息。此时,握手过程结束,客户端和服务器可以开始交换应用层数据了(见上图).注意:为了避免通道延迟,changeCipherspec是一独立的SSL协议的媒体类型,而并非一SSL握手消息.客户端客户端服务器客户端问候服务器问候changeCipherSpec服务器结束changeCipherSpec客户端结束应用数据应用数据客户端首先利用需要重新开始的对话的对话标识符发出客户端问候消息(ClientHellomessage),服务器检查对话缓存来寻找匹配的对话,若找到匹配的对话,服务器将在指定的对话状态下重新建立连接,它将发出带有对话标识符的服务器问候消息(ServerHello)。此时,客户端和服务器均必须发出改变cipherspec消息(changecipherspecmessage)和结束消息(finishedmessage),只要此重新建立连接一完毕,客户端和服务器将交换应用层数据(见上图)。若没找到找到的对话标识符,服务器将产生新的对话标识符,然后SSL客户和服务器将进行正常的握手过程。每一消息的内容和重要性将在以下各节中详细的描述。7。6握手协议SSL握手协议是SSL记录协议(recordProtocol)的一个高级的客户。此协议用来协商一对话的安全参数,握手消息被传给SSL记录层,在那里这些消息被封装在一个或多个SSLPlaintext结构之中,这些SSLPlaintext结构由当前活跃的对话状态中所指定的参数进行处理和传输。enum{hello_request(0),client_hello(1),server_hello(2),certificate(11),server_key_exchange(12),certificate_request(13),server_hello_done(14),certificate_verify(15),client_key_exchange(16),finished(20),(255)}HandshakeType;struct{HandshakeTypemsg_type;/*握手消息的类型*/uint24length;/*握手消息体的字节数*/select(HandshakeType){casehello_request:HelloRequest;caseclient_hello:ClientHello;caseserver_hello:ServerHello;casecertificate:Certificate;caseserver_key_exchange:ServerKeyExchange;casecertificate_request:CertificateRequest;caseserver_hello_done:ServerHelloDone;casecertificate_verify:CertificateVerify;caseclient_key_exchange:ClientKeyExchange;casefinished:Finished;}body;}Handshake;握手协议的消息必须按指定的顺序发出(此顺序如上所示),若不按此顺序发出,则会重新终止性错误.7.6.1问候消息(Hellomessage)问候消息用来在客户端和服务器之间交换彼此安全系统的性能。当一个对话刚开始时,CipherSpec中的加密、杂凑(hash)和压缩算法均初始化为Null,当前的CipherSpec被用来协商这些参数。7.6.1。1Hellorequest要求问候消息(hellorequestmessage)可以由服务器在任何时间发出,但若客户端正在进行握手过程的话,此消息将会被客户端所忽略.它只是一个简单的通知,通知客户端可以在方便的时候发出一客户问候消息(clienthellomessage)来开始一协商的过程。注意:由于握手消息是比应用层数据的传输优先级高,所以协商的时间不应超过最大长度的应用层数据消息的传输时间的一到两倍。在发出要求问候消息之后,在握手协商未完成之前服务器不应再重复发出此消息。一处于协商状态中的客户可以简单的忽略其收到随后要求问候消息。要求问候消息的结构如下: struct{}HelloRequest;7。6.1。2客户问候消息(Clienthello)当一客户第一次与服务器进行连接时,它必须发客户问候消息(Clienthello)作为它的第一个消息。客户也可以将此消息作为对服务器发来的要求问候消息的回应,还可以作为它自己想重新协商一已存在的对话的安全参数的标志发出此消息。客户问候消息(Clienthello)包含一以后会在协议中用到的随机结构struct{uint32gmt_unix_time;opaquerandom_bytes[28];}Random;gmt_unix_time以标准的UNIX的32位形式表示的发出者的内部时钟的当前时间和日期。SSL协议中并不要求时钟必须是准确的,更高级的协议或应用层协议可能会对时钟有更高的要求.random_bytes一由安全随机数发生器产生的28字节的随机数。客户问候消息(Clienthello)包含一可变长度的对话标识符,如果此域的值非空,则此值标识了在同一客户和同一服务器之间的一次对话,此次对话的安全参数是客户端想重新使用的。这个对话的标识符也许是来自一个早期的连接,此次连接,或另一个当前活动的连接。如果客户端仅仅要更新这个随机结构及一次连接的导出值的话,第二种选择是有用的,而第三种选择使得不必完全重复握手协议而同时建立几种同步且独立的安全连接成为可能.对话标识符的实际内容由服务器定义。opaqueSessionID<0。。32>;注意:服务器不能在对话标识符中放置机密信息,不能使假的对话标识符中的内容导致任何泄密。这个包含在由客户端传向服务器的客户问候消息(clienthello)中的加密套接字(CipherSuite)列表包含了加密算法的组合,此列表是客户端所支持的的加密算法的列表,且此列表的顺序是由客户端按其自身的偏爱而选定的(列表的第一项是其最喜爱的).每一CipherSuite同时定义了一个密钥交换算法和一个CipherSpec。服务器将或者选择一个CipherSuite,或者,如果未给出可接受的选择,将返回一个handshakefailure报警并关闭连接。uint8CipherSuite[2];/*加密组选择器*/此客户问候消息(clienthello)包含了一个由客户端支持的压缩算法的列表,且根据客户端的偏好排序.如果服务器不支持客户端所定义的任何一种压缩算法,则此次对话失败。enum{null(0),(255)}CompressionMethod;问题:需要支持哪一种要压缩算法正处于调查之中.客户问候消息(clienthello)的结构如下:struct{ProtocolVersionclient_version;Randomrandom;SessionIDsession_id;CipherSuitecipher_suites<2.。216-1>;CompressionMethodcompression_methods〈1.。28—1〉;}ClientHello;client_version客户端希望在此次对话中使用的SSL协议的版本。这应该是被客户端所支持的最新的版本(最高值)。对于本文所描述的SSL协议,版本号应该是3.0。(关于背景兼容信息请见附录E)。random一个客户端生成的随机结构。session_id客户端在此次连接中想使用的对话标识符(ID)。如果没有可用的session-ID或者客户端想要生成新的加密参数,这个值应该为空.cipher_suites这是一个由客户端支持的,由客户端按其自身的偏爱而选定的加密套接字的列表(列表的第一项是其最喜爱的),如果session_id域非空(暗示重新开始一已有的对话),则此向量必须至少包含来自已有对话的cipher_suite。加密套接字的值的定义见附录A。6。compression_methods这是一个由客户端支持的压缩算法的列表,他根据客户端自身的偏爱而选定的(列表的第一项是其最喜爱的),如果session_id域非空(暗示重新开始一已有的对话),则此向量必须至少包含一个来自已有对话的compression_methods的参数.所有实现均必须支持CompressionMethod.null。继发送clienthello消息之后,客户端等候一个服务器问候消息(serverhellomessage)。除了hello消息外,由服务器返回的任何其他握手消息,均被视为致命错误(fatalerror).实现时注意:只有当结束消息(finishedmessage)发送之后,应用程序的数据才能被发送。在一个合法的结束(finished)消息被收到之前,就传输应用程序的数据被认为是不安全的.如果此次连接有一个当前的,非空的加密,则此绝对的限制将被放宽。7。6。1.3服务器问候消息(Serverhello)服务器处理客户端问候消息(clienthello)并且对客户端问候消息作出握手失败(handshake_failure)警告或者发出服务器问候消息(serverhello)作为响应。struct{ProtocolVersionserver_version;Randomrandom;SessionIDsession_id;CipherSuitecipher_suite;CompressionMethodcompression_method;}ServerHello;server_version这个域将包含客户端在客户端问候消息(clienthello)中建议使用的最低版本和被服务器所支持的最高版本.对于使用本详细说明书的版本来说,版本号应为3.0(关于背景兼容性的详细信息请见附录E)random这个结构由服务器产生,且必须与客户问候消息中的ClientHello。random不同,并且独立于ClientHello.random。session_id这是对应于此次连接的对话标识.若客户问候消息中的ClientHello.session_id非空,服务器将在对话缓存器中寻找匹配的对话。如果匹配被找到并且服务器希望利用给定的对话对话状态码建立一个新的连接,服务器将用与客户问候消息中给定的相同的值响应,这确认了一个重新开始的对话,且对话双方将在收到对方的直到finished消息之前将继续执行下去。否则,这个域将包含一个与客户问候消息中的session_id不同的值以标志一个新的对话。服务器可以返回一个空对话标识(session_id)用来表示这个对话将不会被缓存,而且因此不能被重新开始。Cipher_suite由服务器从客户端问候消息中的ClientHello.cipher_suites列表中选择一个加密套接字而得到的。对于重新开始的对话,此域的值是从重新开始的对话状态字中得到的。compression_method由服务器从客户端问候消息中的compress_method列表中选择的一压缩算法。对于重新开始的对话此域的值是从重新开始的对话状态字中得到的.7.6.2服务器的证书(Servercertificate)如果服务器要求被认证(通常都是这么要求的),则服务器在发出服务器问候消息(serverhellomessage)之后接着发出服务器证书。证书的类型必须是由被选择的加密套接字中密钥交换算法所支持的,通常是X。509.版本3的证书(或是一在Fortezza[FOR]下的修改过的X.509证书.客户端的证书的类型与服务器的证书类型相同。opaqueASN.1Cert〈1。。224-1〉;struct{ASN.1Certcertificate_list〈1。.224—1>;}Certificate;certificate_list证书链中包含一序列X.509。版本3的证书,这些证书的顺序是首先是要验证的一方的证书,然后是发出前一个证书的一方的证书…最后是根的证书。注意:由于没有使用PKCS#6[PKCS6]扩充证书,所以PKCS#7[PKCS7]也不能做为证书向量的格式来使用。且PKCS#7定义了一个集合而不是一个序列,从而使解析证书列表的任务更为复杂.7.6。3服务器密钥交换消息(Serverkeyexchangemessage)若服务器没有证书,或只有供其签名用的公钥证书(例如DSS[DSS]证书,只供签名的RSA[RSA]证书),或使用了Fortezza/DMS密钥交换,则服务器发出服务器密钥交换消息(serverkeyexchangemessage)。当服务器的证书中包含Diffie-Hellman[DH1](即公钥加密)参数时,则不发出此消息。注意:根据当前的美国出口法律,在软件中用于密钥交换的超过512比特的RSA模块是不允许出口的。对于此消息,长的RSA密钥可以做为只用作签名的证书来签用作密钥交换的临时的短的RSA密钥。enum{rsa,diffie_hellman,fortezza_dms}KeyExchangeAlgorithm;struct{opaquersa_modulus<1。.216—1>;opaquersa_exponent<1。。216-1〉;}ServerRSAParams;其中:rsa_modulus服务器的临时的RSA密钥的模数.rsa_exponent服务器的临时的RSA密钥的公开指数。struct{opaquedh_p<1..216-1〉;opaquedh_g<1.。216—1>;opaquedh_Ys〈1..216-1>;}ServerDHParams;/*短期的DH参数*/其中:dh_pDiffie—Hellman操作中用到的质模数。dh_gDiffie-Hellman操作中用到的发生器。dh_Y服务器的Diffie-Hellman公开值(gXmodp).struct{opaquer_s[128];}ServerFortezzaParams;其中:r_s服务器为密钥交换算法而生成的随机数。digitally-signedstruct{select(SignatureAlgorithm){caseanonymous:struct{};casersa:opaquemd5_hash[16];opaquesha_hash[20];casedsa:ﻩopaquesha_hash[20];};}Signature;struct{select(KeyExchangeAlgorithm){casediffie_hellman:ServerDHParamsparams;Signaturesigned_params;casersa:ServerRSAParamsparams;Signaturesigned_params;casefortezza_dms:ServerFortezzaParamsparams;};}ServerKeyExchange;其中:params ﻩﻩ 服务器的密钥交换参数。signed_params ﻩ相应的参数值的哈希值,及对此哈希值的签名。md5_hashMD5(ClientHello。random+Serverhello。random+ServerParams);sha_hashSHA(ClientHello.random+ServerHello。random+ServerParams);enum{anonymous,rsa,dsa}SignatureAlgorithm;7.6.4证书请求(Certificaterequest)如果选择的加密套接字允许的话,一非匿名的服务器可以向客户端要求客户端的证书。enum{rsa_sign(1),dss_sign(2),rsa_fixed_dh(3),dss_fixed_dh(4),rsa_ephemeral_dh(5),dss_ephemeral_dh(6),fortezza_dms(20),(255)}ClientCertificateType;opaqueDistinguishedName<3.。216-1>;struct{ClientCertificateTypecertificate_types<1.。28-1>;DistinguishedNamecertificate_authorities<3。.216—1>;}CertificateRequest;certificate_types此域的值是一被请求的证书的类型的列表,此列表是按服务器的偏好的先后顺序排序的.certificate_authorities是可接受的证书授权当局的唯一的辨别名的列表.注意:唯一的辨别名是由[X509]中导出的.注意:对于一匿名的服务器来说,请求客户端发出客户端的证书是一致命的握手失败报警。7。6.5服务器问候结束(Serverhellodone)由服务器发出的服务器问候结束消息(serverhellodonemessage)是表明服务器问候和其相关的消息的结束。当服务器发出此消息后,它将等待客户端的回应。struct{}ServerHelloDone;当客户端收到服务器问候结束消息(serverhellodonemessage)后,若它要求的话,它将验证服务器的证书是否合法,并且检查在服务器问候消息中的参数是否是可接受的。7.6。6客户端的证书(Clientcertificate)客户端证书是客户端收到服务器问候结束消息(serverhellodonemessage)后所能发出的第一个消息。只有当服务器要求客户端的证书时客户端才发出此消息。如果客户端没有合适的证书,则它发出没有证书报警(nocertificatealert),此报警仅仅是一个警告,若服务器要求客户端认证,则服务器回应一握手失败的致命性的报警。客户端的证书的格式的定义件7。6.2节。注意:客户端的Diffie-Hellman证书必须与服务器指定的Diffie-Hellman参数相匹配.7.6.7客户端密钥交换消息(Clientkeyexchangemessage)是否选择发出此消息依赖于在密钥交换算法定义中选择的公钥算法(见7。6.3节)struct{select(KeyExchangeAlgorithm){casersa:EncryptedPreMasterSecret;casediffie_hellman:ClientDiffieHellmanPublic;casefortezza_dms:FortezzaKeys;}exchange_keys;}ClientKeyExchange;选择合适的记录结构的信息在未决的对话状态字中(见7.1节)。7。6.7。1RSA加密的预主秘密消息(RSAencryptedpremastersecretmessage)若在密钥一致性及认证时使用的是RSA算法,则客户端产生一48比特的预主秘密(pre-mastersecret),并用服务器证书中的公钥或一由服务器密钥交换消息中得到的临时RSA密钥对其进行加密,然后将加密的结果用一加密的预主秘密(encryptedpremastersecret)消息发给服务器。

struct{ProtocolVersionclient_version;opaquerandom[46];}PreMasterSecret;client_version客户端所支持的最新的SSL版本,此域用来发现版本重算攻击(versionroll—backattacks)。random 46比特安全产生的随机数。struct{public-key—encryptedPreMasterSecret pre_master_secret;}EncryptedPreMasterSecret;pre_master_secret由客户端产生的此随机数是用来产生8.1节中说明的主秘密(mastersecret)的。7.6.7.2Fortezza密钥交换消息(Fortezzakeyexchangemessage)在FortezzaDMS下,客户端利用Fortezza密钥交换算法(KEA)得到一标记加密密钥(TokenEncryptionKey(TEK))。客户端利用服务器证书中的服务器公钥和其自身的标记参数来计算KEA,并且利用其自身的参数发出供服务器产生TEK的公开参数.客户端产生对话密钥,用TEK封装后发给服务器;客户端还产生对话密钥的初始向量(IV)和TEK,并将它们发给服务器;它还初始一48比特的随机的预主秘密,用TEK加密后发给服务器。struct{opaquey_c<0..128>;opaquer_c[128];opaquey_signature[20];opaquewrapped_client_write_key[12];opaquewrapped_server_write_key[12];opaqueclient_write_IV[24];opaqueserver_write_IV[24];opaquemaster_secret_IV[24];block-cipheredopaqueencrypted_pre_master_secret[48];}FortezzaKeys;y_signaturey_signature是KEA公钥的签名,是用客户端的DSS私钥签的名.y_c在KEA计算中用到的客户端的Yc值(公钥)。若客户端已发出其证书且KEA公钥是合适的,则由于证书中已有此值,此域可以为空。当客户端发出一密钥合适的公钥的证书的时候,就要有y_c,且y_signature是用客户端DSS私钥签署的KEA公钥的签名。它必须在64至128比特之间。r_c客户端为计算KEA的Rc值。wrapped_client_write_key这是客户端的写密钥,是由TEK封装的。wrapped_server_write_key这是服务器的写密钥,是由TEK封装的。client_write_IV这是客户端的写密钥的初始化向量。server_write_IV这是服务器的写密钥的初始化向量。master_secret_IV这是用来加密预主秘密的TEK的初始化向量。pre_master_secret这是一个由客户端产生的随机数,用来产生8。1节中所描述的主秘密。在上述结构中,它是用TEK加密过的。7。6。7.3客户端Diffie—Hellman公开值(ClientDiffie—Hellmanpublicvalue)若客户端的Diffie—Hellman公开值(Yc)未包含在客户端的证书中的话,此结构将传送它。Yc使用的编码方式是由枚举类型PublicValueEncoding.所决定的。enum{implicit,explicit}PublicValueEncoding;其中:implicit若客户端的证书中已包含此公开值,则它是隐含的,所以Yc不需再传了。ExplicitYc需要被传送。struct{select(PublicValueEncoding){caseimplicit:struct{};caseexplicit:opaquedh_Yc<1.。216—1>;}dh_public;}ClientDiffieHellmanPublic;其中:dh_Yc客户端的Diffie-Hellman公开值(Yc)。7.6。8证书验证(Certificateverify)此消息被用来对客户端的证书提供明显的验证。此消息仅在有签名能力的客户端证书(即没有包含固定的Diffie-Hellman参数的所有证书)发出之后才被发出。struct{Signaturesignature;}CertificateVerify;CertificateVerify.signature。md5_hashMD5(master_secret+pad2+MD5(handshake_messages+master_secret+pad1));Certificate.signature。sha_hashSHA(master_secret+pad2+SHA(handshake_messages+master_secret+pad1));在这里,握手消息(handshake_messages)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论