编程开发 购物 网址 游戏 小说 歌词 地图 快照 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 开发 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
移动开发 架构设计 编程语言 互联网 开发经验 Web前端 开发总结
开发杂谈 系统运维 研发管理 数据库 云 计 算 Java开发
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
  编程开发知识库 -> 互联网 -> SSL握手通信详解及linux下c/c++ SSL Socket代码举例 -> 正文阅读
 

[互联网]SSL握手通信详解及linux下c/c++ SSL Socket代码举例[第1页]

SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
安全证书既包含了用于加密数据的密钥,又包含了用于证实身份的数字签名。安全证书采用公钥加密技术。公钥加密是指使用一对非对称的密钥进行加密或解密。每一对密钥由公钥和私钥组成。公钥被广泛发布。私钥是隐秘的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能被公钥解密。这个非对称的特性使得公钥加密很有用。在安全证书中包含着一对非对称的密钥。只有安全证书的所有者才知道私钥。当通信方A将自己的安全证书发送给通信方B时,实际上发给通信方B的是公开密钥,接着通信方B可以向通信方A发送用公钥加密的数据,只有通信方A才能使用私钥对数据进行解密,从而获得通信方B发送的原始数据。安全证书中的数字签名部分是通信方A的电子身份证。数字签名告诉通信方B该信息确实由通信方A发出,不是伪造的,也没有被篡改。
客户与服务器通信时,首先要进行SSL握手,SSL握手主要完成以下任务:
1)协商使用的加密套件。加密套件中包括一组加密参数,这些参数指定了加密算法和密钥的长度等信息。
2)验证对方的身份,此操作是可选的。
3)确定使用的加密算法。
4)SSL握手过程采用非对称加密方法传递数据,由此来建立一个安全的SSL会话。SSL握手完成后,通信双方将采用对称加密方法传递实际的应用数据。
以下是SSL握手的具体流程:
(1)客户将自己的SSL版本号、加密参数、与SSL会话有关的数据及其他一些必要信息发送到服务器。
(2)服务器将自己的SSL版本号、加密参数、与SSL会话有关的数据及其他一些必要信息发送给客户,同时发给客户的还有服务器的证书。如果服务器需要验证客户身份,服务器还会发出要求客户提供安全证书的请求。
(3)客户端验证服务器证书,如果验证失败,就提示不能建立SSL连接。如果成功,那么继续下一步骤。
(4)客户端为本次SSL会话生成预备主密码(pre-master secret),并将其用服务器公钥加密后发送给服务器。
(5)如果服务器要求验证客户身份,客户端还要对另外一些数据签名后,将其与客户端证书一起发送给服务器。
(6)如果服务器要求验证客户身份,则检查签署客户证书的CA(Certificate Authority,证书机构)是否可信。如果不在信任列表中,结束本次会话。如果检查通过,服务器用自己的私钥解密收到的预备主密码(pre-master secret),并用它通过某些算法生成本次会话的主密码(master secret)。
(7)客户端与服务器端均使用此主密码(master secret)生成此次会话的会话密钥(对称密钥)。在双方SSL握手结束后传递任何消息均使用此会话密钥。这样做的主要原因是对称加密比非对称加密的运算量要低一个数量级以上,能够显著提高双方会话时的运算速度。
(8)客户端通知服务器此后发送的消息都使用这个会话密钥进行加密,并通知服务器客户端已经完成本次SSL握手。
(9)服务器通知客户端此后发送的消息都使用这个会话密钥进行加密,并通知客户端服务器已经完成本次SSL握手。
(10)本次握手过程结束,SSL会话已经建立。在接下来的会话过程中,双方使用同一个会话密钥分别对发送和接收的信息进行加密和解密。
以下为 linux c/c++ SSL socket Client和Server的代码参考。
客户端代码如下:

#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

intOpenConnection(constchar*hostname,intport)

{  intsd;

structhostent *host;

structsockaddr_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, (structsockaddr*)&addr,sizeof(addr)) != 0 )

{

    close(sd);

    perror(hostname);

    abort();

}

returnsd;

}

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();

}

returnctx;

}

voidShowCerts(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");

}

intmain(intcount,char*strings[])

{   SSL_CTX *ctx;

intserver;

SSL *ssl;

charbuf[1024];

intbytes;

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 */

return0;

}

服务端代码如下:

#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

usingnamespacestd;

intOpenListener(intport)

{  intsd;

structsockaddr_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, (structsockaddr*)&addr,sizeof(addr)) != 0 )

{

    perror("can't bind port");

    abort();

}

if( listen(sd, 10) != 0 )

{

    perror("Can't configure listening port");

    abort();

}

returnsd;

}

SSL_CTX* InitServerCTX(void)

{

SSL_CTX *ctx = NULL;

    #if OPENSSL_VERSION_NUMBER >= 0x10000000L

           constSSL_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();

    }

    returnctx;

}

voidLoadCertificates(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");

}

voidShowCerts(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");

}

voidServlet(SSL* ssl)/* Serve the connection -- threadable */

{  charbuf[1024];

charreply[1024];

intsd, bytes;

constchar* 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 */

}

intmain(intcount,char*strings[])

{   SSL_CTX *ctx;

intserver;

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)

{  structsockaddr_in addr;

    socklen_t len =sizeof(addr);

    SSL *ssl;

    intclient = accept(server, (structsockaddr*)&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 */

}

转自SSL握手通信详解及linux C Socket代码举例
阅读全文
本文已收录于以下专栏:

发表评论
HTML/XML objective-c Delphi Ruby PHP C# C++ JavaScript Visual Basic Python Java CSS SQL 其它
相关文章推荐
SSL握手通信详解及linux下c/c++ SSL Socket代码举例
转自: SSL握手通信详解及linux下c/c++ SSL Socket代码举例 SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Lay...
ttomqq 2015-09-07 14:19 628 SSL握手通信详解及linux下c/c++ SSL Socket(另附SSL双向认证客户端代码)
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与...
jsh13417 2014-03-11 22:02 11830 Linux下socket ssl编程
编译程序用下列命令: gcc -Wall ssl-client.c -o client gcc -Wall ssl-server.c -o server 运行程序用如下命令: ./server...
chinabhlt 2015-12-21 17:20 375 Linux下socket ssl编程
Linux下socket ssl编程 摘自:http://www.tootoogo.org/wordpress/?p=611 作者: admin日期: 三月 22, 2011 编译程序...
lzg666456 2015-03-23 08:38 770 Socket通信——Linux下,使用C/C++
本文包含Linux环境下使用C/C++进行socket编程的基础知识,介绍socket建立的过程,创建socket进行通信的几个函数,以及包括TCP socket和UDP socket的简单例子
giantpoplar 2015-08-14 11:50 3900 SM2算法第八篇:SSL Socket通信详解
对称密钥的交换
qq_30866297 2016-05-16 13:31 1136

H3C SSL VPN典型配置举例
2010-11-29 18:27 3.99MB 下载
主题:在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互
Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库  服务端:   ...
hcb1230 2012-09-12 15:47 425 在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互
Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库  服务端:   ...
binyao02123202 2012-06-13 12:47 1636 在Android上实现SSL握手,实现服务器和客户端之间Socket交互
服务端: Java代码 Java代码 public class SSLServer {          private static final int SERVE...
yangxi_001 2012-06-06 16:13 731
myslq +关注
原创 10 粉丝 1 喜欢 0 码云  
他的最新文章 更多文章
常用makefile格式 libcurl+zlib+openssl编译安装 socket模拟http请求
在线课程

【免费】搜狗机器翻译技术分享
讲师:

深度学习在推荐领域的应用和实践
讲师:吴岸城
热门文章 DISTINCT选取多个字段,只DISTINCT一个字段的解决办法
9890
LOAD DATA INFILE语句导入数据进入MySQL的一些注意事项
5802
OpenStack学习:通过devstack安装openstacke mitaka
3226
nginx基于lua-resty-upload实现文件上传
2189
mysql创建外键(Foreign Key)方法
1658
0
  互联网 最新文章
Stanford 英文词性标注(Part-of-speech)缩
基于窗口的实时统计
求解矩阵最短路径问题
SSL握手通信详解及linux下c/c++ SSL Socket
关于服务器上(Docker中)运行Java程序时区
python爬虫系列(六):强大的beautifulsou
[计算机网络笔记]第四部分——网络层 选路算
11.28 北京,念腾讯暑假,不思则惘吧!
web安全之
滑块验证码识别 java版本
上一篇文章      下一篇文章      查看所有文章
加:2017-10-29 21:57:41  更:2017-10-29 21:57:46 
VC(MFC) Delphi VB C++(C语言) C++ Builder 其它开发语言 云计算 Java开发 .Net开发 IOS开发 Android开发 PHP语言 JavaScript
ASP语言 HTML(CSS) HTML5 Apache MSSQL数据库 Oracle数据库 PowerBuilder Informatica 其它数据库 硬件及嵌入式开发 Linux开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年6日历
2018-6-19 22:09:55
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程开发知识库