文档章节

ssl/tls服务通信示例代码

m
 moodlxs
发布于 2016/12/09 17:47
字数 661
阅读 19
收藏 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Ubuntu18.04 显卡GF-940MX安装NVIDIA-390.77

解决办法: 下面就给大家一个正确的姿势在Ubuntu上安装Nvidia驱动: (a)首先去N卡官网下载自己显卡对应的驱动:www.geforce.cn/drivers (b)下载后好放在英文路径的目录下,怎么简单怎么来...

AI_SKI
今天
3
0
深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
今天
1
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
今天
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
3
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部