TLS1.1-握手协议
<DIV>RFC4346中的内容, 摘取了我认为比较重要的部分,做个备忘.</DIV><DIV> </DIV>
<DIV>0. Variants</DIV>
<DIV> Defined structures may have variants based on some knowledge that is<BR> available within the environment. The selector must be an enumerated<BR> type that defines the possible variants the structure defines. There<BR> must be a case arm for every element of the enumeration declared in<BR> the select. The body of the variant structure may be given a label<BR> for reference. The mechanism by which the variant is selected at<BR> runtime is not prescribed by the presentation language.</DIV>
<DIV> struct {<BR> T1 f1;<BR> T2 f2;<BR> ....<BR> Tn fn;<BR> select (E) {<BR> case e1: Te1;<BR> case e2: Te2;<BR> ....<BR> case en: Ten;<BR> } [];<BR> } [];</DIV>
<DIV> For example:</DIV>
<DIV> enum { apple, orange } VariantTag;<BR> struct {<BR> uint16 number;<BR> opaque string<0..10>; /* variable length */<BR> } V1;<BR> struct {<BR> uint32 number;<BR> opaque string; /* fixed length */<BR> } V2;<BR> struct {<BR> select (VariantTag) { /* value of selector is implicit */<BR> case apple: V1; /* VariantBody, tag = apple */<BR> case orange: V2; /* VariantBody, tag = orange */<BR> } variant_body; /* optional label on variant */<BR> } VariantRecord;</DIV>
<DIV> Variant structures may be qualified (narrowed) by specifying a value<BR> for the selector prior to the type. For example, an</DIV>
<DIV> orange VariantRecord</DIV>
<DIV> is a narrowed type of a VariantRecord containing a variant_body of<BR> type V2.</DIV>
<DIV> </DIV>
<DIV>1. RECORD LAYER PROTOCOL:<BR> struct {<BR> uint8 major, minor;<BR> } ProtocolVersion;</DIV>
<DIV> enum {<BR> change_cipher_spec(20), alert(21), handshake(22),<BR> application_data(23), (255)<BR> } ContentType;</DIV>
<DIV> struct {<BR> ContentType type;<BR> ProtocolVersion version;<BR> uint16 length;<BR> opaque fragment;<BR> } TLSPlaintext;</DIV>
<DIV>1.1 HANDSHAKE FLOW:<BR> Client Server</DIV>
<DIV> ClientHello --------><BR> ServerHello<BR> Certificate*<BR> ServerKeyExchange*<BR> CertificateRequest*<BR> <-------- ServerHelloDone<BR> Certificate*<BR> ClientKeyExchange<BR> CertificateVerify*<BR> <BR> Finished --------><BR> <BR> <-------- Finished<BR> Application Data <-------> Application Data</DIV>
<DIV><BR>1.2 HANDSHAKE PROTOCAL:<BR> enum {<BR> hello_request(0), client_hello(1), server_hello(2),<BR> certificate(11), server_key_exchange (12),<BR> certificate_request(13), server_hello_done(14),<BR> certificate_verify(15), client_key_exchange(16),<BR> finished(20), (255)<BR> } HandshakeType;</DIV>
<DIV> struct {<BR> HandshakeType msg_type; /* handshake type */<BR> uint24 length; /* bytes in message */<BR> select (HandshakeType) {<BR> case hello_request: HelloRequest;<BR> case client_hello: ClientHello;<BR> case server_hello: ServerHello;<BR> case certificate: Certificate;<BR> case server_key_exchange: ServerKeyExchange;<BR> case certificate_request: CertificateRequest;<BR> case server_hello_done: ServerHelloDone;<BR> case certificate_verify: CertificateVerify;<BR> case client_key_exchange: ClientKeyExchange;<BR> case finished: Finished;<BR> } body;<BR> } Handshake;</DIV>
<DIV> </DIV>
<DIV>1.2.1 CLIENT_HELLO:<BR> struct {<BR> uint32 gmt_unix_time;<BR> opaque random_bytes;<BR> } Random;<BR> opaque SessionID<0..32>;<BR> uint8 CipherSuite; /* Cryptographic suite selector */<BR> enum { null(0), (255) } CompressionMethod;</DIV>
<DIV><BR> struct {<BR> ProtocolVersion client_version;<BR> Random random;<BR> SessionID session_id;<BR> CipherSuite cipher_suites<2..2^16-1>; <BR> CompressionMethod compression_methods<1..2^8-1>;<BR> } ClientHello;</DIV>
<DIV> 关于客户端的cipher_suites,重要:<BR> cipher_suites<BR> This is a list of the cryptographic options supported by the<BR> client, with the client's first preference first. If the<BR> session_id field is not empty (implying a session resumption<BR> request) this vector MUST include at least the cipher_suite from<BR> that session. Values are defined in Appendix A.5.</DIV>
<DIV> Each CipherSuite defines a key exchange algorithm, a bulk encryption <BR> algorithm (including secret key length), and a MAC algorithm. </DIV>
<DIV><BR>1.2.2 SERVER_HELLO:<BR> struct {<BR> ProtocolVersion server_version;<BR> Random random;<BR> SessionID session_id;<BR> CipherSuite cipher_suite;<BR> CompressionMethod compression_method;<BR> } ServerHello;</DIV>
<DIV> 关于session_id的说明, 涉及复用:<BR> session_id<BR> This is the identity of the session corresponding to this<BR> connection. If the ClientHello.session_id was non-empty, the<BR> server will look in its session cache for a match. If a match is<BR> found and the server is willing to establish the new connection<BR> using the specified session state, the server will respond with<BR> the same value as was supplied by the client. This indicates a<BR> resumed session and dictates that the parties must proceed<BR> directly to the finished messages. Otherwise this field will<BR> contain a different value identifying the new session. The server<BR> may return an empty session_id to indicate that the session will<BR> not be cached and therefore cannot be resumed. If a session is<BR> resumed, it must be resumed using the same cipher suite it was<BR> originally negotiated with.<BR> cipher_suite的说明:<BR> cipher_suite<BR> The single cipher suite selected by the server from the list in<BR> ClientHello.cipher_suites. For resumed sessions, this field is<BR> the value from the state of the session being resumed.</DIV>
<DIV>1.2.3 Server Certificate:<BR> 消息类型(需要查看x509v3的rfc: RFC3280):<BR> opaque ASN.1Cert<1..2^24-1>;</DIV>
<DIV> struct {<BR> ASN.1Cert certificate_list<0..2^24-1>;<BR> } Certificate;</DIV>
<DIV> </DIV>
<DIV> 关于服务端证书的一些说明:<BR> When this message will be sent:</DIV>
<DIV> The server MUST send a certificate whenever the agreed-upon key<BR> exchange method is not an anonymous one. This message will always<BR> immediately follow the server hello message.</DIV>
<DIV> Meaning of this message:</DIV>
<DIV> The certificate type MUST be appropriate for the selected cipher<BR> suite's key exchange algorithm, and is generally an X.509v3<BR> certificate. It MUST contain a key that matches the key exchange<BR> method, as follows. Unless otherwise specified, the signing<BR> algorithm for the certificate MUST be the same as the algorithm<BR> for the certificate key. Unless otherwise specified, the public<BR> key MAY be of any length.</DIV>
<DIV> 密钥交换算法的证书密钥类型:<BR> Key Exchange Algorithm Certificate Key Type</DIV>
<DIV> RSA RSA public key; the certificate MUST<BR> allow the key to be used for encryption.</DIV>
<DIV> DHE_DSS DSS public key.</DIV>
<DIV> DHE_RSA RSA public key that can be used for<BR> signing.</DIV>
<DIV> DH_DSS Diffie-Hellman key. The algorithm used<BR> to sign the certificate MUST be DSS.</DIV>
<DIV> DH_RSA Diffie-Hellman key. The algorithm used<BR> to sign the certificate MUST be RSA.</DIV>
<DIV> All certificate profiles and key and cryptographic formats are<BR> defined by the IETF PKIX working group . When a key usage<BR> extension is present, the digitalSignature bit MUST be set for the<BR> key to be eligible for signing, as described above, and the<BR> keyEncipherment bit MUST be present to allow encryption, as described<BR> above. The keyAgreement bit must be set on Diffie-Hellman<BR> certificates.</DIV>
<DIV><BR> 关于证书链的说明:<BR> Structure of this message:</DIV>
<DIV> opaque ASN.1Cert<1..2^24-1>;</DIV>
<DIV> struct {<BR> ASN.1Cert certificate_list<0..2^24-1>;<BR> } Certificate;</DIV>
<DIV> certificate_list<BR> This is a sequence (chain) of X.509v3 certificates. The sender's<BR> certificate must come first in the list. Each following<BR> certificate must directly certify the one preceding it. Because<BR> certificate validation requires that root keys be distributed<BR> independently, the self-signed certificate that specifies the root<BR> certificate authority may optionally be omitted from the chain,<BR> under the assumption that the remote end must already possess it<BR> in order to validate it in any case.</DIV>
<DIV>1.2.4 Server Key Exchange Message:<BR> 这个需要看下DH交换和RSA交换的RFC,以便理解发送的参数:</DIV>
<DIV> Structure of this message:</DIV>
<DIV> enum { rsa, diffie_hellman } KeyExchangeAlgorithm;</DIV>
<DIV> struct {<BR> opaque rsa_modulus<1..2^16-1>;<BR> opaque rsa_exponent<1..2^16-1>;<BR> } ServerRSAParams;</DIV>
<DIV> rsa_modulus<BR> The modulus of the server's temporary RSA key.</DIV>
<DIV> rsa_exponent<BR> The public exponent of the server's temporary RSA key.</DIV>
<DIV> struct {<BR> opaque dh_p<1..2^16-1>;<BR> opaque dh_g<1..2^16-1>;<BR> opaque dh_Ys<1..2^16-1>;<BR> } ServerDHParams; /* Ephemeral DH parameters */</DIV>
<DIV> dh_p<BR> The prime modulus used for the Diffie-Hellman operation.</DIV>
<DIV> dh_g<BR> The generator used for the Diffie-Hellman operation.</DIV>
<DIV> dh_Ys<BR> The server's Diffie-Hellman public value (g^X mod p).</DIV>
<DIV> struct {<BR> select (KeyExchangeAlgorithm) {<BR> case diffie_hellman:<BR> ServerDHParams params;<BR> Signature signed_params;<BR> case rsa:<BR> ServerRSAParams params;<BR> Signature signed_params;<BR> };<BR> } ServerKeyExchange;<BR> struct {<BR> select (KeyExchangeAlgorithm) {<BR> case diffie_hellman:<BR> ServerDHParams params;<BR> case rsa:<BR> ServerRSAParams params;<BR> };<BR> } ServerParams;</DIV>
<DIV> params<BR> The server's key exchange parameters.</DIV>
<DIV> signed_params<BR> For non-anonymous key exchanges, a hash of the corresponding<BR> params value, with the signature appropriate to that hash<BR> applied.</DIV>
<DIV><BR> md5_hash<BR> MD5(ClientHello.random + ServerHello.random + ServerParams);</DIV>
<DIV> sha_hash<BR> SHA(ClientHello.random + ServerHello.random + ServerParams);</DIV>
<DIV> enum { anonymous, rsa, dsa } SignatureAlgorithm;</DIV>
<DIV><BR> struct {<BR> select (SignatureAlgorithm) {<BR> case anonymous: struct { };<BR> case rsa:<BR> digitally-signed struct {<BR> opaque md5_hash;<BR> opaque sha_hash;<BR> };<BR> case dsa:<BR> digitally-signed struct {<BR> opaque sha_hash;<BR> };<BR> };<BR> };<BR> } Signature;</DIV>
<DIV>1.2.5 Certificate request:<BR> When this message will be sent:</DIV>
<DIV> A non-anonymous server can optionally request a certificate from<BR> the client, if it is appropriate for the selected cipher suite.<BR> This message, if sent, will immediately follow the Server Key<BR> Exchange message (if it is sent; otherwise, the Server Certificate<BR> message).</DIV>
<DIV> Structure of this message:</DIV>
<DIV> enum {<BR> rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),<BR> rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),<BR> fortezza_dms_RESERVED(20), (255)<BR> } ClientCertificateType; </DIV>
<DIV> opaque DistinguishedName<1..2^16-1>;</DIV>
<DIV> struct {<BR> ClientCertificateType certificate_types<1..2^8-1>;<BR> DistinguishedName certificate_authorities<0..2^16-1>;<BR> } CertificateRequest;</DIV>
<DIV> certificate_types<BR> This field is a list of the types of certificates requested,<BR> sorted in order of the server's preference.<BR> Values from 0 (zero) through 63 decimal (0x3F) inclusive are<BR> reserved for IETF Standards Track protocols.</DIV>
<DIV> certificate_authorities<BR> A list of the distinguished names of acceptable certificate<BR> authorities. These distinguished names may specify a desired<BR> distinguished name for a root CA or for a subordinate CA; thus,<BR> this message can be used to describe both known roots and a<BR> desired authorization space. If the certificate_authorities<BR> list is empty then the client MAY send any certificate of the<BR> appropriate ClientCertificateType, unless there is some<BR> external arrangement to the contrary.</DIV>
<DIV> Note: It is a fatal handshake_failure alert for an anonymous server<BR> to request client authentication.</DIV>
<DIV><BR>1.2.6 Server Hello Done<BR> 服务端发送这个消息表示server hello阶段的结束. 服务端发送此消息后将会<BR> 等待客户端的回应.此消息意味着服务端支持key exchange的消息发送完毕,<BR> 客户端可以继续它自己的key exchange的阶段.收到服务端的这个消息,客户端<BR> SHOULD确认服务端提供了一个有效的证书(如果需要)并且检查server hello的<BR> 参数是可接受的.<BR> <BR> Structure of this message:</DIV>
<DIV> struct { } ServerHelloDone;</DIV>
<DIV>1.2.7 Client certificate<BR> When this message will be sent:<BR> 这是客户端收到server_hello_done之后发送的第一个消息.客户端发送此消<BR> 息只有服务端发送了certificate_request消息时. 如果无可用证书,客户端<BR> SHOULD发送一个不包含证书的证书消息.也就是length为0的certificate_list<BR> 结构.如果服务端对于客户端验证时require的,那将会导致一个fatal <BR> handshake failure alert.</DIV>
<DIV> Note: When using a static Diffie-Hellman based key exchange method<BR> (DH_DSS or DH_RSA), if client authentication is requested, the<BR> Diffie-Hellman group and generator encoded in the client's<BR> certificate MUST match the server specified Diffie-Hellman<BR> parameters if the client's parameters are to be used for the key<BR> exchange.</DIV>
<DIV>1.2.8 Client Key Exchange Message:<BR> When this message will be sent:<BR> 由客户端发送,且MUST紧跟client certificate message(如果发送),否则<BR> 就作为收到server hello done之后的第一个消息.</DIV>
<DIV> Meaning of this message:</DIV>
<DIV> With this message, the premaster secret is set, either though<BR> direct transmission of the RSA-encrypted secret or by the<BR> transmission of Diffie-Hellman parameters that will allow each<BR> side to agree upon the same premaster secret. When the key<BR> exchange method is DH_RSA or DH_DSS, client certification has been<BR> requested, and the client was able to respond with a certificate<BR> that contained a Diffie-Hellman public key whose parameters (group<BR> and generator) matched those specified by the server in its<BR> certificate, this message MUST not contain any data.</DIV>
<DIV> Structure of this message:</DIV>
<DIV> The choice of messages depends on which key exchange method has<BR> been selected. See Section 1.2.4 for the KeyExchangeAlgorithm<BR> definition.</DIV>
<DIV> struct {<BR> select (KeyExchangeAlgorithm) {<BR> case rsa: EncryptedPreMasterSecret;<BR> case diffie_hellman: ClientDiffieHellmanPublic;<BR> } exchange_keys;<BR> } ClientKeyExchange;</DIV>
<DIV>1.2.8.1 RSA Encrypted Premaster Secret Message<BR> Meaning of this message:<BR> If RSA is being used for key agreement and authentication, the<BR> client generates a 48-byte premaster secret, encrypts it using the<BR> public key from the server's certificate or the temporary RSA key<BR> provided in a server key exchange message, and sends the result in<BR> an encrypted premaster secret message. This structure is a<BR> variant of the client key exchange message and is not a message in<BR> itself.</DIV>
<DIV> Structure of this message:<BR> struct {<BR> ProtocolVersion client_version;<BR> opaque random;<BR> } PreMasterSecret;</DIV>
<DIV> client_version The latest (newest) version supported by the<BR> client. This is used to detect version roll-back attacks.<BR> Upon receiving the premaster secret, the server SHOULD check<BR> that this value matches the value transmitted by the client in<BR> the client hello message.</DIV>
<DIV> random<BR> 46 securely-generated random bytes.</DIV>
<DIV> struct {<BR> public-key-encrypted PreMasterSecret pre_master_secret;<BR> } EncryptedPreMasterSecret;</DIV>
<DIV> pre_master_secret<BR> This random value is generated by the client and is used to<BR> generate the master secret.</DIV>
<DIV>1.2.8.2 Client Diffie-Hellman Public Value<BR> Meaning of this message:</DIV>
<DIV> This structure conveys the client's Diffie-Hellman public value<BR> (Yc) if it was not already included in the client's certificate.<BR> The encoding used for Yc is determined by the enumerated<BR> PublicValueEncoding. 这个是一个变体,不是消息本身.</DIV>
<DIV> Structure of this message:</DIV>
<DIV> enum { implicit, explicit } PublicValueEncoding;</DIV>
<DIV> implicit<BR> If the client certificate already contains a suitable Diffie-<BR> Hellman key, then Yc is implicit and does not need to be sent<BR> again. In this case, the client key exchange message will be<BR> sent, but it MUST be empty.</DIV>
<DIV> explicit<BR> Yc needs to be sent.</DIV>
<DIV> struct {<BR> select (PublicValueEncoding) {<BR> case implicit: struct { };<BR> case explicit: opaque dh_Yc<1..2^16-1>;<BR> } dh_public;<BR> } ClientDiffieHellmanPublic;</DIV>
<DIV> dh_Yc<BR> The client's Diffie-Hellman public value (Yc).</DIV>
<DIV>1.2.9 Certificate verify<BR> When this message will be sent:</DIV>
<DIV> This message is used to provide explicit verification of a client<BR> certificate.When<BR> sent, it MUST immediately follow the client key exchange message.</DIV>
<DIV> Structure of this message:</DIV>
<DIV> struct {<BR> Signature signature;<BR> } CertificateVerify;</DIV>
<DIV> The Signature type is defined in 1.2.4.</DIV>
<DIV> CertificateVerify.signature.md5_hash<BR> MD5(handshake_messages);</DIV>
<DIV> CertificateVerify.signature.sha_hash<BR> SHA(handshake_messages);</DIV>
<DIV> Here handshake_messages refers to all handshake messages sent or<BR> received starting at client hello up to but not including this<BR> message, including the type and length fields of the handshake<BR> messages. </DIV>
<DIV>1.2.10 Finished(密文的,抓包看不到的)<BR> When this message will be sent:</DIV>
<DIV> A finished message is always sent immediately after a change<BR> cipher spec message to verify that the key exchange and<BR> authentication processes were successful. It is essential that a<BR> change cipher spec message be received between the other handshake<BR> messages and the Finished message.(中间的change cipher spec是必要的)</DIV>
<DIV> Meaning of this message:</DIV>
<DIV> The finished message is the first protected with the just-<BR> negotiated algorithms, keys, and secrets. Recipients of finished<BR> messages MUST verify that the contents are correct. Once a side<BR> has sent its Finished message and received and validated the<BR> Finished message from its peer, it may begin to send and receive<BR> application data over the connection.</DIV>
<DIV> Structure of this message:<BR> struct {<BR> opaque verify_data;<BR> } Finished;</DIV>
<DIV> verify_data<BR> PRF(master_secret, finished_label, MD5(handshake_messages) +<BR> SHA-1(handshake_messages)) ;<BR> finished_label<BR> For Finished messages sent by the client, the string "client<BR> finished". For Finished messages sent by the server, the<BR> string "server finished".</DIV>
<DIV> handshake_messages<BR> All of the data from all messages in this handshake (not<BR> including any HelloRequest messages) up to but not including<BR> this message. This is only data visible at the handshake<BR> layer and does not include record layer headers. This is the<BR> concatenation of all the Handshake structures, as defined in<BR> 7.4, exchanged thus far.</DIV>
<DIV>2 Cryptographic Computations<BR> 为了保护连接, TLS的记录层需要一组算法,主密钥,服务端和客户端随机数的<BR> 详细说明. authentication, encryption, and MAC algorithms由服务端选择<BR> 的cipher_suite决定,并在server hello消息中指明.压缩算法在hello消息中<BR> 协商.所有上述这些都用作计算主密钥.</DIV>
<DIV>2.1. Computing the Master Secret<BR> For all key exchange methods, the same algorithm is used to convert<BR> the pre_master_secret into the master_secret. The pre_master_secret<BR> should be deleted from memory once the master_secret has been<BR> computed.<BR> master_secret = PRF(pre_master_secret, "master secret",<BR> ClientHello.random + ServerHello.random)<BR> ;</DIV>
<DIV> The master secret is always exactly 48 bytes in length. The length<BR> of the premaster secret will vary depending on key exchange method.</DIV>
<DIV> </DIV>
<DIV>2.1.1. RSA</DIV>
<DIV> When RSA is used for server authentication and key exchange, a 48-<BR> byte pre_master_secret is generated by the client, encrypted under<BR> the server's public key, and sent to the server. The server uses its<BR> private key to decrypt the pre_master_secret. Both parties then<BR> convert the pre_master_secret into the master_secret, as specified<BR> above.</DIV>
<DIV> RSA digital signatures are performed using PKCS #1 block type<BR> 1. RSA public key encryption is performed using PKCS #1 block type 2.</DIV>
<DIV>2.1.2. Diffie-Hellman</DIV>
<DIV> A conventional Diffie-Hellman computation is performed. The<BR> negotiated key (Z) is used as the pre_master_secret, and is converted<BR> into the master_secret, as specified above. Leading bytes of Z that<BR> contain all zero bits are stripped before it is used as the<BR> pre_master_secret.</DIV>
<DIV> Note: Diffie-Hellman parameters are specified by the server and may<BR> be either ephemeral or contained within the server's<BR> certificate.</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><BR> </DIV>
<DIV></DIV>
<DIV></DIV>
页:
[1]