文档章节

ssl/tls服务通信示例代码

m
 moodlxs
发布于 2016/12/09 17:47
字数 661
阅读 22
收藏 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
粉丝 7
博文 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
HTTPS与HTTP区别 -- TLS/SSL

一直困扰于HTTP和HTTPS的区别,现在专门找一个时间来抓住痛点,解决掉该麻烦。 1. HTTP + 加密 + 认证 + 完整性保护 = HTTPS 我们知道HTTP是明文传输的,就必不可免存在如下问题: 重要数据被...

lanzry
03/20
0
0
stunnel 4.44 发布,TLS/SSL服务软件

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

小卒过河
2011/09/18
483
0
stunnel 4.43 发布,TLS/SSL服务软件

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

红薯
2011/09/08
225
1

没有更多内容

加载失败,请刷新页面

加载更多

java框架学习日志-7(静态代理和JDK代理)

静态代理 我们平时去餐厅吃饭,不是直接告诉厨师做什么菜的,而是先告诉服务员点什么菜,然后由服务员传到给厨师,相当于服务员是厨师的代理,我们通过代理让厨师炒菜,这就是代理模式。代理...

白话
26分钟前
5
0
Flink Window

1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻...

满小茂
27分钟前
3
0
my.ini

1

architect刘源源
43分钟前
3
0
docker dns

There is a opensource application that solves this issue, it's called DNS Proxy Server It's a DNS server that solves containers hostnames, if could not found a hostname that mat......

kut
51分钟前
5
0
寻找数学的广度——《这才是数学》读书笔记2700字

寻找数学的广度——《这才是数学》读书笔记2700字: 文|程哲。数学学习方式之广:国内外数学教育方面的专家,进行了很多种不同的数学学习方式尝试,如数学绘本、数学游戏、数学实验、数学步道...

原创小博客
57分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部