SSL(四)

客户端代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define FAIL    -1
int OpenConnection(const char *hostname, int port)
{   int sd;
struct hostent *host;
struct sockaddr_in addr;
if ( (host = gethostbyname(hostname)) == NULL )
{
    printf('Eroor: %s\n',hostname);
    perror(hostname);
    abort();
}
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = *(long*)(host->h_addr);
if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
    close(sd);
    perror(hostname);
    abort();
}
return sd;
}
SSL_CTX* InitCTX(void)
{   SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */
SSL_load_error_strings();   /* Bring in and register error messages */
method = SSLv2_client_method();  /* Create new client-method instance */
ctx = SSL_CTX_new(method);   /* Create new context */
if ( ctx == NULL )
{
    ERR_print_errors_fp(stderr);
    printf('Eroor: %s\n',stderr);
    abort();
}
return ctx;
}
void ShowCerts(SSL* ssl)
{   X509 *cert;
    char *line;
    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
    if ( cert != NULL )
    {
    printf("Server certificates:\n");
    line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
    printf("Subject: %s\n", line);
    free(line);       /* free the malloc'ed string */
    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
    printf("Issuer: %s\n", line);
    free(line);       /* free the malloc'ed string */
    X509_free(cert);     /* free the malloc'ed certificate copy */
}
else
    printf("No certificates.\n");
}
int main(int count, char *strings[])
{   SSL_CTX *ctx;
int server;
SSL *ssl;
char buf[1024];
int bytes;
char *hostname, *portnum;
if ( count != 3 )
{
    printf("usage: %s <hostname> <portnum>\n", strings[0]);
    exit(0);
}
SSL_library_init();
hostname=strings[1];
portnum=strings[2];
ctx = InitCTX();
server = OpenConnection(hostname, atoi(portnum));
ssl = SSL_new(ctx);      /* create new SSL connection state */
SSL_set_fd(ssl, server);    /* attach the socket descriptor */
if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
{
    printf('Eroor: %s\n',stderr);
    ERR_print_errors_fp(stderr);
}
else
{   char *msg = "HelloWorld";
    printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
    ShowCerts(ssl);        /* get any certs */
    SSL_write(ssl, msg, strlen(msg));   /* encrypt & send message */
    bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
    buf[bytes] = 0;
    printf("Received: \"%s\"\n", buf);
    SSL_free(ssl);        /* release connection state */
}
close(server);         /* close socket */
SSL_CTX_free(ctx);        /* release context */
return 0;
}


服务端代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"
#define FAIL    -1
using namespace std;
int OpenListener(int port)
{   int sd;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
    perror("can't bind port");
    abort();
}
if ( listen(sd, 10) != 0 )
{
    perror("Can't configure listening port");
    abort();
}
return sd;
}
SSL_CTX* InitServerCTX(void)
{
SSL_CTX *ctx = NULL;
    #if OPENSSL_VERSION_NUMBER >= 0x10000000L
           const SSL_METHOD *method;
    #else
            SSL_METHOD *method;
    #endif
    SSL_library_init();
    OpenSSL_add_all_algorithms();  /* load & register all cryptos, etc. */
    SSL_load_error_strings();   /* load all error messages */
    method = SSLv23_client_method(); /* create new server-method instance */
    ctx = SSL_CTX_new(method);   /* create new context from method */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
//New lines
    if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
        ERR_print_errors_fp(stderr);
    if (SSL_CTX_set_default_verify_paths(ctx) != 1)
        ERR_print_errors_fp(stderr);
    //End new lines
/* set the local certificate from CertFile */
if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
{
    ERR_print_errors_fp(stderr);
    abort();
}
/* set the private key from KeyFile (may be the same as CertFile) */
if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
{
    ERR_print_errors_fp(stderr);
    abort();
}
/* verify private key */
if ( !SSL_CTX_check_private_key(ctx) )
{
    fprintf(stderr, "Private key does not match the public certificate\n");
    abort();
}
printf("LoadCertificates Compleate Successfully.....\n");
}
void ShowCerts(SSL* ssl)
{   X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
if ( cert != NULL )
{
    printf("Server certificates:\n");
    line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
    printf("Subject: %s\n", line);
    free(line);
    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
    printf("Issuer: %s\n", line);
    free(line);
    X509_free(cert);
}
else
    printf("No certificates.\n");
}
void Servlet(SSL* ssl) /* Serve the connection -- threadable */
{   char buf[1024];
char reply[1024];
int sd, bytes;
const char* HTMLecho="<html><body><pre>%s</pre></body></html>\n\n";
if ( SSL_accept(ssl) == FAIL )     /* do SSL-protocol accept */
    ERR_print_errors_fp(stderr);
else
{
    ShowCerts(ssl);        /* get any certificates */
    bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
    if ( bytes > 0 )
    {
        buf[bytes] = 0;
        printf("Client msg: \"%s\"\n", buf);
        sprintf(reply, HTMLecho, buf);   /* construct reply */
        SSL_write(ssl, reply, strlen(reply)); /* send reply */
    }
    else
        ERR_print_errors_fp(stderr);
}
sd = SSL_get_fd(ssl);       /* get socket connection */
SSL_free(ssl);         /* release SSL state */
close(sd);          /* close connection */
}
int main(int count, char *strings[])
{   SSL_CTX *ctx;
int server;
char *portnum;
if ( count != 2 )
{
    printf("Usage: %s <portnum>\n", strings[0]);
    exit(0);
}
else
{
    printf("Usage: %s <portnum>\n", strings[1]);
}
SSL_library_init();
portnum = strings[1];
ctx = InitServerCTX();        /* initialize SSL */
LoadCertificates(ctx, "/home/stud/kawsar/mycert.pem""/home/stud/kawsar/mycert.pem");  /* load certs */
server = OpenListener(atoi(portnum));    /* create server socket */
while (1)
{   struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    SSL *ssl;
    int client = accept(server, (struct sockaddr*)&addr, &len);  /* accept connection   as usual */
    printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    ssl = SSL_new(ctx);              /* get new SSL state with context */
    SSL_set_fd(ssl, client);      /* set connection socket to SSL state */
    Servlet(ssl);         /* service connection */
}
close(server);          /* close server socket */
SSL_CTX_free(ctx);         /* release context */
}
<think>好的,我现在需要回答用户关于SSL次握手和TCP三次握手的问题。首先,用户之前询问过SSL协议原理和加密算法,现在进一步询问SSL次握手和TCP三次握手的区别。我需要确保回答准确,同时结构清晰,符合用户之前的要求。 首先,我需要确认自己对这两个概念的理解是否正确。TCP三次握手是建立连接的过程,而SSL次握手(更准确地说,TLS握手)是在TCP连接之后建立安全通道的过程。用户可能想知道这两者的步骤和区别,以及它们如何协同工作。 接下来,我需要回忆TCP三次握手的具体步骤:SYN、SYN-ACK、ACK。然后是TLS握手的步骤,通常包括ClientHello、ServerHello、证书交换、密钥交换等。不过TLS握手通常被称为次握手,但实际步骤可能更多,可能需要更详细的解释。 需要注意的是,用户提到的“SSL次握手”可能指的是TLS握手过程,因为SSL已经被TLS取代,但通常人们仍用SSL来泛指。我需要澄清这一点,避免混淆。 另外,用户可能希望了解这两个过程在建立安全连接中的顺序和作用。TCP三次握手建立传输层连接,而TLS握手在应用层建立加密通信。需要分步骤说明,并指出它们分别属于不同层次。 同时,要确保使用中文,并且按照之前的格式,使用分点、数学公式等。例如,在解释密钥交换时使用数学公式,如Diffie-Hellman的公式,或者RSA加密的公式。 需要检查是否有错误的地方,比如是否混淆了SSL和TLS,或者步骤是否有遗漏。例如,TLS 1.3简化了握手步骤,可能需要提到版本差异,但用户可能主要关注传统流程。 最后,总结两者的关系和区别,帮助用户理解整个连接建立过程。可能还需要提到端口号,如TCP使用443端口进行HTTPS连接,而三次握手是任何TCP连接的基础。 现在需要组织这些信息,按照用户之前接受的格式,分步骤详细说明,使用适当的LaTeX公式,确保正确性,并保持结构清晰。</think>以下是TCP三次握手与SSL/TLS次握手的详细对比说明(基于OSI模型分层解析): --- ### 一、TCP三次握手(传输层协议) **作用**:建立可靠的端到端连接,协商初始序列号 **数学表达**: 设客户端初始序列号$ISN_c$,服务端初始序列号$ISN_s$ 1. SYN:$Client \rightarrow Server$ $SEQ = ISN_c,\quad FLAGS = SYN$ 2. SYN-ACK:$Server \rightarrow Client$ $SEQ = ISN_s,\quad ACK = ISN_c+1,\quad FLAGS = SYN|ACK$ 3. ACK:$Client \rightarrow Server$ $SEQ = ISN_c+1,\quad ACK = ISN_s+1,\quad FLAGS = ACK$ **关键特征**: - 通过$\text{SEQ/ACK}$实现数据包顺序控制 - 典型端口:HTTP-80 / HTTPS-443 - 状态变迁:CLOSED → SYN_SENT → ESTABLISHED --- ### 二、SSL/TLS次握手(应用层安全协议) **作用**:协商加密参数,建立安全通信信道 **标准流程**(以RSA密钥交换为例): 1. **ClientHello** - 协议版本(TLS 1.2/1.3) - 随机数$ClientRandom$ - 支持的加密套件列表 $$ \text{示例:TLS\_ECDHE\_RSA\_WITH\_AES\_128\_GCM\_SHA256} $$ 2. **ServerHello** - 选定加密套件 - 随机数$ServerRandom$ - 发送数字证书(含RSA公钥) $$ \text{证书链验证:Root CA → Intermediate CA → Server Certificate} $$ 3. **ClientKeyExchange** - 生成预主密钥: $$ PremasterSecret = RSA\_Encrypt(ClientRandom, ServerRandom) $$ - 计算主密钥: $$ MasterSecret = PRF(PremasterSecret, "master secret", ClientRandom + ServerRandom) $$ 4. **Finished** - 生成会话密钥: $$ SessionKeys = PRF(MasterSecret, "key expansion", ServerRandom + ClientRandom) $$ - 验证哈希: $$ VerifyData = HMAC\_SHA256(MasterSecret, handshake\_messages) $$ **密钥交换优化**(ECDHE方案): $$ \text{临时椭圆曲线参数:} Q_{server} = d_{server} \times G $$ $$ \text{共享密钥:} Z = d_{client} \times Q_{server} = d_{server} \times Q_{client} $$ --- ### 三、协议交互时序对比 | 对比维度 | TCP三次握手 | SSL/TLS次握手 | |----------------|-------------------------------|-----------------------------------| | OSI层级 | 传输层(第4层) | 应用层(第7层) | | 主要目标 | 建立可靠传输通道 | 建立加密通信信道 | | 典型耗时 | 1-2 RTT | 2 RTT(RSA) / 1 RTT(TLS 1.3) | | 加密保护 | 无 | 支持AES/ChaCha20等算法 | | 密钥管理 | 不涉及 | 包含密钥交换与协商机制 | | 数据完整性 | 仅校验序列号 | 使用HMAC-SHA256等验证 | --- ### 、完整HTTPS连接建立流程 1. TCP三次握手(传输层连接) ```mermaid sequenceDiagram Client->>Server: SYN (SEQ=ISN_c) Server->>Client: SYN-ACK (SEQ=ISN_s, ACK=ISN_c+1) Client->>Server: ACK (SEQ=ISN_c+1, ACK=ISN_s+1) ``` 2. TLS次握手(安全信道建立) ```mermaid sequenceDiagram Client->>Server: ClientHello (TLS版本+加密套件+ClientRandom) Server->>Client: ServerHello (选定参数+ServerRandom) + Certificate Client->>Server: ClientKeyExchange (加密的PremasterSecret) Server->>Client: ChangeCipherSpec + Finished (加密验证) ``` --- ### 五、性能优化实践 1. **TLS会话恢复**: - Session ID复用:服务端缓存$MasterSecret$ - Session Tickets:客户端存储加密的会话状态 2. **协议升级**: - TLS 1.3 0-RTT:对安全请求允许首个数据包携带应用数据 $$ EarlyData = AES\_GCM\_Encrypt(early\_traffic\_secret, data) $$ 3. **硬件加速**: - 使用支持AES-NI指令集的CPU提升对称加密性能 - 部署支持ECC加速的密码卡(如:国密SM2算法)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值