`
bogongjie
  • 浏览: 235909 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

C TLS 通讯

    博客分类:
  • C
C 
阅读更多

1. TLS 通讯server sample: server.c

 

#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"

int OpenListener(int port){   
    int sd;
    struct sockaddr_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, (struct sockaddr*)&addr, sizeof(addr)) != 0 ){
        perror("can't bind port");
        abort();
    }
    if ( listen(sd, 10) != 0 ){
        perror("Can't configure listening port");
        abort();
    }
    return sd;
}
SSL_CTX* InitServerCTX(void){   
    const SSL_METHOD *method;
    SSL_CTX *ctx;
    OpenSSL_add_all_algorithms();  /* load & register all cryptos, etc. */
    SSL_load_error_strings();   /* load all error messages */
    method = TLSv1_2_server_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();
    }
    return ctx;
}
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile){
    if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
        ERR_print_errors_fp(stderr);

    SSL_CTX_set_default_passwd_cb_userdata(ctx, "xxxxx");

    if (SSL_CTX_set_default_verify_paths(ctx) != 1)
        ERR_print_errors_fp(stderr);

    /* 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();
    }

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
    SSL_CTX_set_verify_depth(ctx, 4);
}
void ShowCerts(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");
    }
}
void Servlet(SSL* ssl){ /* Serve the connection -- threadable */   
    char buf[1024] = {0};
    int sd, bytes;
    const char* ServerResponse="receive and return content";
    const char *cpValidMessage = "helloword";							 
    if ( SSL_accept(ssl) == -1 ){     /* do SSL-protocol accept */
        ERR_print_errors_fp(stderr);
    }else{
        ShowCerts(ssl);        /* get any certificates */
        bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
        buf[bytes] = '\0';
        printf("Client msg: \"%s\"\n", buf);

        const char *cpRequestMessage = "this is content from client: \"%s\" and send to client";
        char acClientRequest[1024] ={0};							 
        sprintf(acClientRequest, cpRequestMessage, buf);

        if ( bytes > 0 ){
            //if(strcmp(cpValidMessage,buf) == 0){
            //    SSL_write(ssl, ServerResponse, strlen(ServerResponse)); /* send reply */
            //}else{
                SSL_write(ssl, acClientRequest, strlen(acClientRequest)); /* 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 */
}
int main(int count, char *Argc[]){   
    SSL_CTX *ctx;
    int server;
    char *portnum;
    if ( count != 2 ){
        printf("Usage: %s <portnum>\n", Argc[0]);
        exit(0);
    }
    // Initialize the SSL library
    SSL_library_init();
    portnum = Argc[1];
    ctx = InitServerCTX();        /* initialize SSL */
    LoadCertificates(ctx, "cert.pem", "key.pem"); /* load certs */
    server = OpenListener(atoi(portnum));    /* create server socket */
    while (1){   
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL *ssl;
        int client = accept(server, (struct sockaddr*)&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 */
}

 编译命令: gcc -Wall -o server  server.c -L/usr/lib -lssl -lcrypto 

 

 

2. TLS 通讯client sample: client.c

 

#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
int OpenConnection(const char *hostname, int port){   
    int sd;
    struct hostent *host;
    struct sockaddr_in addr;
    if ( (host = gethostbyname(hostname)) == NULL ){
        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, (struct sockaddr*)&addr, sizeof(addr)) != 0 ){
        close(sd);
        perror(hostname);
        abort();
    }
    return sd;
}
SSL_CTX* InitCTX(void){   
    const 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 = TLSv1_2_client_method();  /* Create new client-method instance */
    ctx = SSL_CTX_new(method);   /* Create new context */
    if ( ctx == NULL ){
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}
void ShowCerts(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("Info: No client certificates configured.\n");
    }
}
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile){
    /* 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();
    }
}
int main(int count, char *strings[]){   
    SSL_CTX *ctx;
    int server;
    SSL *ssl;
    char buf[5000];
    char acClientRequest[5000] ={0};
    int bytes;
    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();
    printf("start load mycert1.pem file!\n"); //server request client send certificates file, otherwise can not receive msg
    LoadCertificates(ctx, "cert.pem", "key.pem"); /* load certs */
    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 */
        ERR_print_errors_fp(stderr);
    }else{  
        char acUsername[16] ={0};
        const char *quit = "exit";
        //char acPassword[16] ={0};
        //const char *cpRequestMessage = "<Body><UserName>%s<UserName><Password>%s<Password><\Body>";	
        while(1){
            const char *cpRequestMessage = "%s";							 
            printf("please enter the transport content : ");
            scanf("%s",acUsername);
            sprintf(acClientRequest, cpRequestMessage, acUsername);
            const char *a123 = acUsername;
            int index = strncmp(a123, quit,strlen(quit));
            printf("strncmp = %d\n",index);
            if( index == 0){
                break;
            }
            printf("\n\nConnected with %s encryption\n", SSL_get_cipher(ssl));
            ShowCerts(ssl);        /* get any certs */
            SSL_write(ssl,acClientRequest, strlen(acClientRequest));   /* encrypt & send message */
            bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
            buf[bytes] = 0;
            printf("Received: \"%s\"\n", buf);
            memset(buf,0,sizeof(buf));
        }
        SSL_free(ssl);        /* release connection state */
    }
    close(server);         /* close socket */
    SSL_CTX_free(ctx);        /* release context */
    return 0;
}

 编译命令: gcc -Wall -o client  client.c -L/usr/lib -lssl -lcrypto

 

 

3. 生成私钥文件和生成自签署证书:

openssl genrsa -des3 -out key.pem 2048 //使用密码

openssl genrsa -out key.pem 2048

 

 

openssl req -new -x509 -key key.pem -days 3665 -out cert.pem

-new 为生成新的证书,会要求用户填写相关的信息

-x509 通常用于自签署证书,生成测试证书或用于CA自签署 

-key私钥位置  

-days申请的天数(默认30天) 

 

-out生成位置

 

参考链接:

https://wiki.openssl.org/index.php/Simple_TLS_Server

https://stackoverflow.com/questions/11705815/client-and-server-communication-using-ssl-c-c-ssl-protocol-dont-works

分享到:
评论

相关推荐

    mbedtls-2.13 最新

    mbed tls 被设计成以嵌入式环境作为主要目标的便携式C语言,运行在像ARM和AVR到PCS和iPad,iphones甚至是xbox这样的嵌入式平台上. 作者:程序手艺人 链接:https://www.jianshu.com/p/26084e8665cd 來源:简书 简书...

    通讯加密证书 TLS详解.pdf

    ### 通讯加密证书 TLS详解 #### 一、什么是TLS TLS(Transport Layer Security)即传输层安全性协议,是一种广泛应用于互联网安全通信的标准协议。它的前身是SSL(Secure Sockets Layer)。TLS采用C/S架构(客户端...

    STM32 实现SSL通讯

    本篇文章将基于STM32F217xx微控制器的应用笔记(AN3365),探讨其如何实现SSL(Secure Sockets Layer)/TLS(Transport Layer Security)加密通讯,并提供详细的背景介绍、技术分析及实际应用案例。 #### 二、SSL/...

    Linux下C语言实现即时通讯系统.zip

    在Linux环境下,使用C语言开发即时通讯系统是一项挑战性但极具价值的任务。C语言作为底层编程的首选,能够提供高效且灵活的控制,适合构建这样的系统。即时通讯系统(Instant Messaging System, IMS)通常涉及客户端...

    联盛德W601使用mbedTLS软件包与HTTPS服务器建立安全通讯连接【RT-Thread工程,支持W60X系列单片机】

    联盛德W601驱动程序是为该微控制器设计的一组软件模块,它允许开发者通过编程控制硬件资源,如GPIO、ADC、SPI、I2C等。这些驱动程序是操作系统和硬件之间的桥梁,确保了软件与硬件间的正确交互,使开发者能专注于...

    商业编程-源码-C语言写的通讯管理系统.zip

    【C语言编写的通讯管理系统】 在商业环境中,通信管理系统是一个至关重要的工具,它帮助企业高效地管理内部和外部的通信流程。这个系统通常包括多种功能,如邮件管理、短信通知、通话记录、客户联系信息存储等。...

    Implementing SSL TLS Using Cryptography and PKI

    在使用C语言实现SSL/TLS时,开发者需要对C语言编程以及网络编程有一定的了解,同时必须熟悉SSL/TLS协议的细节和加密技术。此外,还需要关注相关的安全实践和最佳实践,确保实现的安全性和效率。 总结: 通过学习和...

    使用paho-mqtt-c做的mqtt通讯

    `paho-mqtt-c`是Eclipse Paho项目的一部分,它提供了C语言版本的MQTT客户端接口,便于开发者在各种平台上进行MQTT应用的开发。 首先,让我们深入了解一下`paho-mqtt-c`库。这个库提供了完整的MQTT客户端功能,包括...

    ssl双向认证 ,客户端c代码

    主要介绍openssl进行客户端-服务器双向验证的通信,客户端应该如何设置。包括了如何使用openssl指令生成客户端-服务端的证书和密钥,以及使用openssl自带server端来实现简单的ssl双向认证,client端代码中也做了相应...

    计网小作业之基于C/S模式的即时通讯软件

    本项目名为“计网小作业之基于C/S模式的即时通讯软件”,它旨在实现一个简单的即时通讯系统,该系统采用经典的客户端/服务器(C/S)架构。下面将详细介绍这个项目涉及的关键知识点。 一、C/S模式 C/S(Client/...

    即时通讯系统源码 飞机即时通讯源码 适配iOS安卓系统源码.zip

    在iOS平台上,即时通讯系统的实现通常涉及到Objective-C或Swift编程语言。苹果提供了多套API来支持网络通信,例如Foundation框架中的URLSession,用于HTTP/HTTPS请求;MultipeerConnectivity框架,用于设备间点对点...

    linux下c语言实现xml传输方式的即时通讯

    在Linux环境下,使用C语言实现XML传输方式的即时通讯是一个涉及多方面技术栈的项目。以下将详细解析这个主题中的关键知识点。 首先,C语言是系统级编程的基础,它的低级特性和高效性能使得它非常适合在Linux这样的...

    P2P即时通讯_P2P_即时通讯_P2P即时通讯_

    P2P即时通讯技术是一种基于对等网络架构的通信方式,它不同于传统的客户端-服务器(C/S)模式,其中每个用户既是服务的消费者也是服务的提供者。在P2P即时通讯系统中,用户之间可以直接交换信息,无需通过中心服务器...

    52im即时通讯源码 带安卓和iso源码

    1. 开发环境:iOS客户端使用Xcode开发,遵循Swift或Objective-C编程语言。 2. UI设计:与Android类似,iOS客户端也需要创建用户交互界面,包括登录、聊天等页面。 3. 协议实现:iOS客户端同样需要实现WebSocket或...

    c语言下基于Linux的即时通讯软件

    在C语言下基于Linux开发即时通讯软件是一项技术性极强的工作,它涉及到多个领域的知识,包括网络编程、多线程、进程通信、字符编码、数据结构以及用户界面设计等。以下将详细介绍这些关键知识点。 1. **C语言编程...

    Linux下的及时通讯系统

    可以使用SSL/TLS协议进行数据传输加密,C语言中有OpenSSL库提供支持。另外,防止SQL注入和XSS攻击也是必要的安全措施。 5. **状态机设计**:为了处理登录注册、私聊群聊、踢人禁言等各种状态转换,可以设计状态机...

    即时通讯源码,自己收集的,多为C#

    - **安全与加密**:为了保护用户的隐私和数据安全,即时通讯软件通常会使用SSL/TLS等协议加密通信内容。 - **用户界面**:C#的Windows Forms或WPF提供用于创建现代、互动的用户界面的工具。 4. **源码下载器.exe*...

    使用TLS加密通讯远程连接Docker的示例详解

    docker context create mysecurecontext --docker "tls=true,tls.cert=/path/to/client-cert.pem,tls.key=/path/to/client-key.pem,tls.ca=/path/to/ca.pem" ``` 之后,使用`docker context use mysecurecontext`...

    即时通讯(C_Video).rar

    即时通讯(C_Video).rar 是一个关于C#实现视频通讯技术和Socket通讯的压缩包文件,其中可能包含了源代码、教程文档等资源,帮助学习者深入理解和实践这两种技术。即时通讯技术通常用于构建实时的在线聊天、视频会议...

    即时通讯软件C

    6. **安全性**:即时通讯软件必须保证通信的安全性,这可能涉及到加密技术,如SSL/TLS用于保护数据传输安全,或者使用端到端加密确保只有发送方和接收方能解密消息。 7. **用户界面**:用户友好且响应迅速的界面是...

Global site tag (gtag.js) - Google Analytics