SSL双方系统时间不一致导致的SSL连接失败及其解决方案
来源:互联网 发布:决对争锋网络剧资源 编辑:程序博客网 时间:2024/05/24 04:21
在产品使用中,实施人员常常报告服务器与客户端无法连接.究其原因是因为客户端机器与服务端机器系统时间不一致.原因在于系统使用了OpenSSL,证书中有一个有效时间段,当客户端或服务器的系统时间不在这个时间段内时SSL会因证书验证失败而无法连接.在实施中系统时间错误是很常见的,因不能上网而未开时间自动同步,bios没电了,客户疏忽等原因都会导致系统时间设置有误.如果连接失败后再查看系统时间设置总是一项麻烦的事情,那么有哪些办法可以自动避免这个问题呢?
一,将证书的有效期设得够大:如:1970-2099
这样估计可以在一定程度上解决这个问题,不过这也是个馊主意.
二,检测及必要时自动同步客户端与服务器的时间
一,将证书的有效期设得够大:如:1970-2099
这样估计可以在一定程度上解决这个问题,不过这也是个馊主意.
二,检测及必要时自动同步客户端与服务器的时间
通过用wireshake抓包分析SSL建立连接的过程,发现在SSL握手过程中,会向对方传送本机的系统时间.因此一个显而易见的办法就是获取对方的时间,然后在必要时将本机的系统时间改为对方的系统时间,失败后再连一次.下面是具体的示例代码:
#include <openssl/ssl.h>#include <openssl/bio.h>#include <openssl/err.h>#include <winsock2.h>#include <stdio.h>#include <string.h>#include <time.h>typedef struct _TimeInfo{ time_t client; /*客户端的时间*/ time_t server; /*服务器的时间*/} TimeInfo;/*** 同步系统时间.*/BOOL syncSystemTime(time_t t){ SYSTEMTIME st; FILETIME ft; LONGLONG ll; ll = Int32x32To64(t, 10000000) + 116444736000000000; //1970.01.01 ft.dwLowDateTime = (DWORD)ll; ft.dwHighDateTime = (DWORD)(ll >> 32); return FileTimeToSystemTime(&ft, &st) && SetSystemTime(&st);}/*** 获取SSL握手过程中服务器与客户端双方的系统时间.*/void getSSLHandleShakeTimeInfo(int write_p, int version, int content_type, const unsigned char* buf, size_t len, SSL *ssl, TimeInfo *ti){ if(content_type != 22) //require handshake message return; if(len < 42) return; if(buf[0] == 1) //ClientHello Message send from client to server ti->client = htonl(*((u_long*)(buf + 6))); else if(buf[0] == 2) //ServerHello Message send from server to client ti->server = htonl(*((u_long*)(buf + 6))); else return;}int main(){ BIO * bio; SSL * ssl; SSL_CTX * ctx; TimeInfo timeInfo = {-1, -1}; BOOL timeSynced = FALSE; long result; /* Set up the library */ SSL_library_init(); ERR_load_BIO_strings(); SSL_load_error_strings(); /* Set up the SSL context */ ctx = SSL_CTX_new(SSLv3_client_method()); if(ctx == NULL) { fprintf(stderr, "Error new SSL_CTX\n"); ERR_print_errors_fp(stderr); SSL_CTX_free(ctx); return 0; } /* Get Server and Client system time via SSL Handshake */ SSL_CTX_set_msg_callback(ctx, getSSLHandleShakeTimeInfo); SSL_CTX_set_msg_callback_arg(ctx, &timeInfo); /* Load the trust store */ if(! SSL_CTX_load_verify_locations(ctx, ".\\certs\\cacert.pem", NULL)) { fprintf(stderr, "Error loading trust store\n"); ERR_print_errors_fp(stderr); SSL_CTX_free(ctx); return 0; } /* Setup the connection */ bio = BIO_new_ssl_connect(ctx); /* Set the SSL_MODE_AUTO_RETRY flag */ BIO_get_ssl(bio, & ssl); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* Create and setup the connection */ BIO_set_conn_hostname(bio, "192.168.1.5:5555"); if(BIO_do_connect(bio) <= 0) { fprintf(stderr, "Error attempting to connect\n"); ERR_print_errors_fp(stderr); BIO_free_all(bio); SSL_CTX_free(ctx); return 0; } /* Check the certificate */ switch(SSL_get_verify_result(ssl)) { case X509_V_OK: break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_HAS_EXPIRED: if(timeInfo.server != -1 && timeInfo.client != -1) { printf("当前客户端时间: %s", ctime(&timeInfo.client)); printf("当前服务器时间: %s", ctime(&timeInfo.server)); printf("尝试与服务器时间同步"); if(syncSystemTime(timeInfo.server)) printf("成功\n"); else printf("失败\n"); printf("请重试连接服务器!\n"); } default: fprintf(stderr, "Certificate verification error: %i\n", SSL_get_verify_result(ssl)); BIO_free_all(bio); SSL_CTX_free(ctx); return 0; } /* Close the connection and free the context */ BIO_free_all(bio); SSL_CTX_free(ctx); return 0;}
0 0
- SSL双方系统时间不一致导致的SSL连接失败及其解决方案
- Tomcat启用SSL导致Firefox出现“安全连接失败”错误的解决方法
- 因服务器时间不一致导致的MapRecude 任务运行失败
- 信息化失败的根源之一 甲乙双方目标不一致
- 因证书别名不一致导致不能启动SSL通道
- Java的SSL连接
- 解决使用libpq时提示一系列SSL相关函数没有定义导致编译失败的问题
- 项目jdk版本不一致导致Tomcat启动失败解决方案
- Tomcat使用SSL的连接
- Tomcat使用SSL的连接
- mIRC的SSL连接问题
- Tomcat使用SSL的连接
- 配置oracle的ssl连接
- DataPackage-数据库、表的区域设置和系统不一致导致处理失败
- 修改时间不一致导致的编译错误
- Open JDK 建立SSL失败的问题
- 俄语版JDK取的时间与系统时间不一致的解决方案
- SSL协议及其应用
- linux date 操作
- OCP 1Z0 051 164
- 设计模式(16)-行为型模式-ITERATOR模式
- Linux hostname主机名配置文件/etc/hosts详解 详细出处参考:http://www.jb51.net/LINUXjishu/77329.html
- 8086汇编自娱自乐
- SSL双方系统时间不一致导致的SSL连接失败及其解决方案
- makefile
- 关于.h与h的区别
- jquery改变form属性,提交表单
- 大三上学期,图形编程基础
- python类方法和静态方法
- 设计模式(17)-行为型模式-Moderator模式
- python django 与数据库的交互
- 【数据库】sql2008卸载和默认实例的删除