文档章节

ssl/tls服务通信示例代码

m
 moodlxs
发布于 2016/12/09 17:47
字数 661
阅读 21
收藏 0

注意:使用相同的ca生成两个证书,一个是server.cer,一个是client.cer,注意生成server.cer的时候必须指明证书可以用于服务端的。

server端:

#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

#include  <unistd.h>
#include  <sys/types.h>       /* basic system data types */
#include  <sys/socket.h>      /* basic socket definitions */
#include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
#include  <arpa/inet.h>       /* inet(3) functions */
#include <sys/epoll.h> /* epoll function */
#include <fcntl.h>     /* nonblocking */
#include <sys/resource.h> /*setrlimit */

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#define EXIT_IF_TRUE(x) if (x)                              \
do {                                                    \
    fprintf(stderr, "Check '%s' is true\n", #x);    \
        ERR_print_errors_fp(stderr);                    \
        exit(2);                                        \
}while(0)

int main(int argc, char **argv)
{
    SSL_CTX     *ctx;
    SSL         *ssl;
    X509        *client_cert;

    char szBuffer[1024];
    int nLen;

    struct sockaddr_in addr;
    int len;
    int nListenFd, nAcceptFd;

    // 初始化
    SSLeay_add_ssl_algorithms();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ERR_load_BIO_strings();

    // 我们使用SSL V3,V2
    EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);

    // 要求校验对方证书
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

    // 加载CA的证书
    EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));

    // 加载自己的证书
    EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "server.cer", SSL_FILETYPE_PEM) <= 0) ;

    // 加载自己的私钥
    EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) ;

    // 判定私钥是否正确
    EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));

    // 创建并等待连接
    nListenFd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in servaddr;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
    servaddr.sin_port = htons (19821);

    if (bind(nListenFd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1) 
    {
        perror("bind error");
        return -1;
    }

    if (listen(nListenFd, 1024) == -1) 
    {
        perror("listen error");
        return -1;
    }

    memset(&addr, 0, sizeof(addr));
    len = sizeof(addr);
    nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (socklen_t *)&len);
    printf("Accept a connect from [%s:%d]\n", 
            inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

    // 将连接付给SSL
    EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);
    SSL_set_fd (ssl, nAcceptFd);
    EXIT_IF_TRUE( SSL_accept (ssl) != 1);

    // 进行操作
    memset(szBuffer, 0, sizeof(szBuffer));
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);
    strcat(szBuffer, " this is from server");
    SSL_write(ssl, szBuffer, strlen(szBuffer));

    // 释放资源
    SSL_free (ssl);
    SSL_CTX_free (ctx);
    close(nAcceptFd);
}

 

客户端:

#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"

#include  <unistd.h>
#include  <sys/types.h>       /* basic system data types */
#include  <sys/socket.h>      /* basic socket definitions */
#include  <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
#include  <arpa/inet.h>       /* inet(3) functions */
#include <sys/select.h>       /* select function*/

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>


#define EXIT_IF_TRUE(x) if (x)    \
do {                                                    \
    fprintf(stderr, "Check '%s' is true\n", #x);    \
        ERR_print_errors_fp(stderr);                    \
        exit(2);                                        \
}while(0)

int main(int argc, char **argv)
{
    SSL_METHOD  *meth;
    SSL_CTX     *ctx;
    SSL         *ssl;

    int nFd;
    int nLen;
    char szBuffer[1024];

    // 初始化
    SSLeay_add_ssl_algorithms();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ERR_load_BIO_strings();

    // 我们使用SSL V3,V2    
    EXIT_IF_TRUE((ctx = SSL_CTX_new (SSLv23_method())) == NULL);

    // 要求校验对方证书
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

    // 加载CA的证书
    EXIT_IF_TRUE (!SSL_CTX_load_verify_locations(ctx, "cacert.cer", NULL));

    // 加载自己的证书
    EXIT_IF_TRUE (SSL_CTX_use_certificate_file(ctx, "client.cer", SSL_FILETYPE_PEM) <= 0) ;

    // 加载自己的私钥
    EXIT_IF_TRUE (SSL_CTX_use_PrivateKey_file(ctx, "client.key", SSL_FILETYPE_PEM) <= 0) ;

    // 判定私钥是否正确
    EXIT_IF_TRUE (!SSL_CTX_check_private_key(ctx));

    // 创建连接
    nFd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in servaddr;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(19821);
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

    if (connect(nFd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
        perror("connect error");
        return -1;
    }

    // 将连接付给SSL
    EXIT_IF_TRUE( (ssl = SSL_new (ctx)) == NULL);
    SSL_set_fd (ssl, nFd);
    EXIT_IF_TRUE( SSL_connect (ssl) != 1);

    // 进行操作
    sprintf(szBuffer, "this is from client %d", getpid());
    SSL_write(ssl, szBuffer, strlen(szBuffer));

    // 释放资源
    memset(szBuffer, 0, sizeof(szBuffer));
    nLen = SSL_read(ssl,szBuffer, sizeof(szBuffer));
    fprintf(stderr, "Get Len %d %s ok\n", nLen, szBuffer);

    SSL_free (ssl);
    SSL_CTX_free (ctx);
    close(nFd);
}

 

© 著作权归作者所有

共有 人打赏支持
m
粉丝 6
博文 41
码字总数 168307
作品 0
深圳
高级程序员
关于https的那些事儿

关于https的那些事儿 某学姐2017-03-1612 阅读 前一阵子在研究抓包原理,发现https抓包和普通的http抓包原理完全不同。而在了解https抓包之前,有必要先掌握https协议的通信过程。 于是在写这...

某学姐
2017/03/16
0
0
TLS/SSL服务软件--stunnel

Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel 可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like...

匿名
2010/03/25
1K
0
stunnel 4.43 发布,TLS/SSL服务软件

Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel 可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like...

红薯
2011/09/08
217
1
stunnel 4.48 发布,TLS/SSL服务软件

Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel 可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like...

红薯
2011/11/27
458
0
stunnel 4.44 发布,TLS/SSL服务软件

Stunnel是一个自由的跨平台软件,用于提供全局的TLS/SSL服务。针对本身无法进行TLS或SSL通信的客户端及服务器,Stunnel 可提供安全的加密连接。该软件可在许多操作系统下运行,包括Unix-like...

小卒过河
2011/09/18
477
0

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
今天
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
今天
14
1
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部