在Linux上使用OpenSSL进行SSL/TLS握手可以通过多种方式实现和调试。以下是详细说明:
openssl s_client -connect example.com:443 -showcerts
这个命令会: 1. 连接到example.com的443端口 2. 显示完整的SSL握手过程 3. 显示服务器返回的证书链
openssl s_client -connect example.com:443 -debug -state -tlsextdebug
参数说明:
- -debug
:显示详细的调试信息
- -state
:显示握手状态变化
- -tlsextdebug
:显示TLS扩展信息
# 强制使用TLS 1.2
openssl s_client -connect example.com:443 -tls1_2
# 强制使用TLS 1.3
openssl s_client -connect example.com:443 -tls1_3
openssl s_client -connect example.com:443 -cipher 'ALL:COMPLEMENTOFALL'
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
int main() {
SSL_library_init();
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) {
ERR_print_errors_fp(stderr);
return 1;
}
// 创建TCP连接
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(443);
inet_pton(AF_INET, "93.184.216.34", &addr.sin_addr); // example.com的IP
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) {
perror("connect failed");
return 1;
}
// 创建SSL连接
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
if (SSL_connect(ssl) <= 0) {
ERR_print_errors_fp(stderr);
} else {
printf("SSL/TLS握手成功\n");
printf("使用的协议: %s\n", SSL_get_version(ssl));
printf("使用的密码套件: %s\n", SSL_get_cipher(ssl));
// 获取服务器证书
X509 *cert = SSL_get_peer_certificate(ssl);
if (cert) {
char *line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("证书主题: %s\n", line);
free(line);
X509_free(cert);
}
}
SSL_shutdown(ssl);
SSL_free(ssl);
close(sock);
SSL_CTX_free(ctx);
return 0;
}
编译命令:
gcc ssl_client.c -o ssl_client -lssl -lcrypto
查看详细的错误信息:
openssl s_client -connect example.com:443 -showcerts -debug -state
检查证书链:
openssl s_client -connect example.com:443 -showcerts | openssl x509 -noout -text
验证证书:
openssl verify -CAfile /path/to/ca-bundle.crt server-cert.pem
"sslv3 alert handshake failure":
"certificate verify failed":
-CAfile
参数指定CA证书包"unsupported protocol":
使用Wireshark抓包分析:
tls
或ssl
协议OpenSSL内置诊断:
openssl s_client -connect example.com:443 -msg
检查服务器支持的协议和密码套件:
nmap --script ssl-enum-ciphers -p 443 example.com
通过这些方法和工具,你可以全面分析和调试OpenSSL在Linux上的SSL/TLS握手过程。