当前位置: 技术问答>linux和unix
OpenSSL编程中,如何实现session重用
来源: 互联网 发布时间:2014-12-21
本文导语: 重谢!(包括客户和服务器) | Listing 3. Setting Client Authentication Mode 158 switch(client_auth){ 159 case CLIENT_AUTH_REQUEST: 160 SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0); 161 ...
重谢!(包括客户和服务器)
|
Listing 3. Setting Client Authentication Mode
158 switch(client_auth){
159 case CLIENT_AUTH_REQUEST:
160 SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);
161 break;
162 case CLIENT_AUTH_REQUIRE:
163 SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER |
164 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
165 break;
166 case CLIENT_AUTH_REHANDSHAKE:
167 /* Do nothing */
168 break;
169 }
At this point you might ask, "Why not just require client authentication from the beginning?". For some applications doing so would be just as good but for a real web server it might not be. Imagine that you have a web server that requires SSL for all requests but has a super-secure section for which you want to require certificate-based authentication. Because the SSL handshake occurs before the HTTP request is transmitted, there's no way to tell in advance which part of the web site the client wants to access, and therefore whether client authentication is required.
The workaround is to allow the client to connect without client authentication. The server then reads the client's request and determines whether or not client authentication is required. If it is, it requests a new SSL handshake and requires client authentication. However, since this code is demonstration code, we don't bother to actually examine the client request. We simply force a rehandshake if the -x flag is specified.
Rehandshaking on the Server
The OpenSSL rehandshake API is unfortunately pretty complicated. In order to understand it you first need to understand a little bit about how SSL rehandshake works. Ordinarily the client initiates the SSL handshake by sending a ClientHello message to the server. The client can initiate a rehandshake simply by sending a new ClientHello. If the server wishes to initiate a rehandshake, it sends a HelloRequest message. When it receives a HelloRequest the client may--or may not--initiate a new handshake. Moreover, handshake messages are part of a different stream of data, so data can be flowing while the handshake is happening.
Listing 4 shows the code necessary to implement the rehandshake. The first thing we do is use SSL_set_verify() to tell the server to require the client to perform client authentication. Unfortunately, this setting only controls what OpenSSL does on new handshakes. If a client were to attempt a resumed handshake, this setting would be ignored. To prevent this problem we use SSL_set_session_id_context() to set the resumption context to s_server_auth_session_id_context, instead of s_server_session_id_context.
It's worth taking a minute to understand why changing the session ID context works. Whenever an SSL object stores a session in the session cache, it tags it with the current ID context. Before resuming a session, OpenSSL checks that the current ID context matches the one stored with the cache--but only if SSL_VERIFY_PEER is set. Therefore, changing our ID context ensures that the client can't simply resume the session it just created, because it was created under a different ID context. However, if the client had previously communicated with the server and established a client authenticated session under s_server_auth_session_id_context, then it could resume that session.
Only checking the session ID context if SSL_VERIFY_PEER is set is somewhat counterintuitive; the intent is to ensure that you don't resume sessions in one context that were client authenticated in another context, perhaps with different certificate checking rules. Presumably the idea is that aside from client authentication, one session is rather like another. This assumption is somewhat questionable; one might similarly wish to prevent a session established with one set of cipher preferences from being resumed in an SSL object with a different set of cipher preferences. The only way to accomplish this separation with OpenSSL is to use a totally different SSL_CTX for each cipher suite policy.
Next, we call SSL_negotiate() to move the connection into renegotiate state. Note that this does not cause the connection to be renegotiated; it merely sets the renegotiate flag in the object so that when we call SSL_do_handshake(), the server sends a HelloRequest. Note that the server doesn't do the entire handshake at this point. That requires a separate call to SSL_do_handshake().
Does a good farmer neglect a crop he has planted?
Does a good teacher overlook even the most humble student?
Does a good
|
下面的例子绝对对你有帮助
Session Resumption
When a client and server establish an SSL connection for the first time, they need to establish a shared key called the master_secret. The master_secret is then used to create all the bulk encryption keys used to protect the traffic. The master_secret is almost invariably established using one of two public key algorithms: RSA or Diffie-Hellman (DH). Unfortunately, both of these algorithms are quite slow--on my Pentium II/400 a single RSA operation takes 19 ms. DH can be even slower.
An operation that takes 19 ms may not sound that expensive, but if it has to be done for every connection, it limits the server's throughput to less than 50 connections/second. Without SSL, most web servers can handle hundreds of connections a second. Thus, having to do a key exchange for every client seriously degrades the performance of a web server. In order to improve performance, SSL contains a "session resumption" feature that allows a client/server pair to skip this time consuming step if they have already established a master_secret in a previous connection.
The performance of RSA is highly asymmetric. Operations performed with the private key (such as when the server decrypts the shared key) are much slower than operations performed with the public key. Thus, in most situations most of the computational load is on the server.
What's a Session?
SSL makes a distinction between a connection and a session. A connection represents one specific communications channel (typically mapped to a TCP connection), along with its keys, cipher choices, sequence number state, etc. A session is a virtual construct representing the negotiated algorithms and the master_secret . A new session is created every time a given client and server go through a full key exchange and establish a new master_secret.
Multiple connections can be associated with a given session. Although all connections in a given session share the same master_secret, each has its own encryption keys. This is absolutely necessary for security reasons because reuse of bulk keying material can be extremely dangerous. Resumption allows the generation of a new set of bulk keys and IVs from a common master_secret because the keys depend on the random values, which are fresh for each connection. The new random values are combined with the old master_secret to produce new keys.
How It Works
The first time a client and server interact, they create both a new connection and a new session. If the server is prepared to resume the session, it assigns the session a session_id and transmits the session_id to the client during the handshake. The server caches the master_secret for later reference. When the client initiates a new connection with the server, it provides the session_id to the server. The server can choose to either resume the session or force a full handshake. If the server chooses to resume the session, the rest of the handshake is skipped, and the stored master_secret is used to generate all the cryptographic keys.
Session Resumption on the Client
Listing 1 shows the minimal OpenSSL code required for a client to do session resumption. OpenSSL uses a SESSION object to store the session information, and SSL_get1_session() allows us to get the SESSION for a given SSL object. Once we have obtained the SESSION object we shut down the original connection (using SSL_shutdown()) and create a new SSL object. We use SSL_set_session() to attach the SESSION to the new SSL object before calling SSL_connect(). This causes OpenSSL to attempt to resume the session when it connects to the server. This code is activated by using the -r flag to wclient2.
Listing 1. Reconnect to the Server with Resumed Session
144 /* Now hang up and reconnect, if requested */
145 if(reconnect) {
146 sess=SSL_get1_session(ssl); /*Collect the session*/
147 SSL_shutdown(ssl);
148 SSL_free(ssl);
149 close(sock);
150
151 sock=tcp_connect(host,port);
152 ssl=SSL_new(ctx);
153 sbio=BIO_new_socket(sock,BIO_NOCLOSE);
154 SSL_set_bio(ssl,sbio,sbio);
155 SSL_set_session(ssl,sess); /*And resume it*/
156 if(SSL_connect(ssl)
Session Resumption
When a client and server establish an SSL connection for the first time, they need to establish a shared key called the master_secret. The master_secret is then used to create all the bulk encryption keys used to protect the traffic. The master_secret is almost invariably established using one of two public key algorithms: RSA or Diffie-Hellman (DH). Unfortunately, both of these algorithms are quite slow--on my Pentium II/400 a single RSA operation takes 19 ms. DH can be even slower.
An operation that takes 19 ms may not sound that expensive, but if it has to be done for every connection, it limits the server's throughput to less than 50 connections/second. Without SSL, most web servers can handle hundreds of connections a second. Thus, having to do a key exchange for every client seriously degrades the performance of a web server. In order to improve performance, SSL contains a "session resumption" feature that allows a client/server pair to skip this time consuming step if they have already established a master_secret in a previous connection.
The performance of RSA is highly asymmetric. Operations performed with the private key (such as when the server decrypts the shared key) are much slower than operations performed with the public key. Thus, in most situations most of the computational load is on the server.
What's a Session?
SSL makes a distinction between a connection and a session. A connection represents one specific communications channel (typically mapped to a TCP connection), along with its keys, cipher choices, sequence number state, etc. A session is a virtual construct representing the negotiated algorithms and the master_secret . A new session is created every time a given client and server go through a full key exchange and establish a new master_secret.
Multiple connections can be associated with a given session. Although all connections in a given session share the same master_secret, each has its own encryption keys. This is absolutely necessary for security reasons because reuse of bulk keying material can be extremely dangerous. Resumption allows the generation of a new set of bulk keys and IVs from a common master_secret because the keys depend on the random values, which are fresh for each connection. The new random values are combined with the old master_secret to produce new keys.
How It Works
The first time a client and server interact, they create both a new connection and a new session. If the server is prepared to resume the session, it assigns the session a session_id and transmits the session_id to the client during the handshake. The server caches the master_secret for later reference. When the client initiates a new connection with the server, it provides the session_id to the server. The server can choose to either resume the session or force a full handshake. If the server chooses to resume the session, the rest of the handshake is skipped, and the stored master_secret is used to generate all the cryptographic keys.
Session Resumption on the Client
Listing 1 shows the minimal OpenSSL code required for a client to do session resumption. OpenSSL uses a SESSION object to store the session information, and SSL_get1_session() allows us to get the SESSION for a given SSL object. Once we have obtained the SESSION object we shut down the original connection (using SSL_shutdown()) and create a new SSL object. We use SSL_set_session() to attach the SESSION to the new SSL object before calling SSL_connect(). This causes OpenSSL to attempt to resume the session when it connects to the server. This code is activated by using the -r flag to wclient2.
Listing 1. Reconnect to the Server with Resumed Session
144 /* Now hang up and reconnect, if requested */
145 if(reconnect) {
146 sess=SSL_get1_session(ssl); /*Collect the session*/
147 SSL_shutdown(ssl);
148 SSL_free(ssl);
149 close(sock);
150
151 sock=tcp_connect(host,port);
152 ssl=SSL_new(ctx);
153 sbio=BIO_new_socket(sock,BIO_NOCLOSE);
154 SSL_set_bio(ssl,sbio,sbio);
155 SSL_set_session(ssl,sess); /*And resume it*/
156 if(SSL_connect(ssl)
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
站内导航:
特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!