美文网首页
ssl 编程服务器和客户端完整demo c++版

ssl 编程服务器和客户端完整demo c++版

作者: 海阔天空的博客 | 来源:发表于2021-10-31 05:59 被阅读0次

ssl 编程服务器和客户端完整demo c++版,编译环境:cent os 64, g++

安装openssl:

yum search opensll #查找可用的openssl开发包
yum install opensll-devel.x86_64   #从查找结果中选择安装 devel 版本

生成ca文件和key文件,供服务器使用

openssl genrsa -out privkey.pem 2048
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095

服务器代码:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define MAXBUF 1024
 
const int s_myport = 8081;
 
int main(int argc, char **argv)
{
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    char buf[MAXBUF + 1];
    SSL_CTX *ctx;
 
    SSL_library_init();
    OpenSSL_add_all_algorithms();
 
    SSL_load_error_strings();
 
    ctx = SSL_CTX_new(SSLv23_server_method());
 
    if (ctx == NULL) 
    {
        ERR_print_errors_fp(stdout);
        printf("---1\n");
        exit(1);
    }
 
    if (SSL_CTX_use_certificate_file(ctx, argv[1], SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stdout);
         printf("---2:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", argv[1]);
        exit(1);
    }
 
    if (SSL_CTX_use_PrivateKey_file(ctx, argv[2], SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stdout);
         printf("---3:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", argv[2]);
        exit(1);
    }
 
    if (!SSL_CTX_check_private_key(ctx)) 
    {
         printf("---4\n");
        ERR_print_errors_fp(stdout);
        exit(1);
    }
 
 
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) 
    {
         printf("---5\n");
        perror("socket");
        exit(1);
    } 
    else
    {
        printf("socket created\n");
    }
 
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(s_myport);
    my_addr.sin_addr.s_addr = INADDR_ANY;
 
    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) 
    {
        perror("bind");
        exit(1);
    } 
    else
    {
        printf("binded\n");
    }
    unsigned int lisnum = 1;
    if (listen(sockfd, lisnum) == -1) 
    {
        perror("listen");
        exit(1);
    } 
    else
    {
        printf("begin listen\n");
    }
     
    while (1) 
    {
        SSL *ssl;
        len = sizeof(struct sockaddr);
 
        if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len)) == -1)
        {
            perror("accept");
            exit(errno);
        } 
        else
        {
        printf("server: got connection from {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s, port {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d, socket {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);
        }
 
        ssl = SSL_new(ctx);
 
        SSL_set_fd(ssl, new_fd);
 
        if (SSL_accept(ssl) == -1) 
        {
            perror("accept");
            close(new_fd);
            break;
        }
 
 
        bzero(buf, MAXBUF + 1);
        strcpy(buf, "hello, this is server");
 
        len = SSL_write(ssl, buf, strlen(buf));
 
        if (len <= 0) 
        {
            printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n",buf, errno, strerror(errno));
            goto finish;
        } 
        else
        {
            //printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s, {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d\n", buf, len);
        }
 
        bzero(buf, MAXBUF + 1);
 
        len = SSL_read(ssl, buf, MAXBUF);
        if (len > 0)
        {
            printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s, {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d\n", buf, len);
        }
        else
        {
            printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s'\n", errno, strerror(errno));
        }
 
finish:
        SSL_shutdown(ssl);
        SSL_free(ssl);
        close(new_fd);
    }
 
 
    close(sockfd);
 
    SSL_CTX_free(ctx);
    return 0;
}

客户端代码:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
 
#define MAXBUF 1024
 
void ShowCerts(SSL * ssl)
{
    X509 *cert;
    char *line;
 
    cert = SSL_get_peer_certificate(ssl);
    if (cert != NULL)
    {
        printf("show:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("one: {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("two {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", line);
        free(line);
         
        char commonName [512] = {0};
        X509_NAME * name = NULL;
        name = X509_get_subject_name(cert);
        X509_NAME_get_text_by_NID(name, NID_commonName, commonName, 512);
        printf("debug-name:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", commonName);
         
        X509_free(cert);
    } 
    else
    {
        printf("error\n");
    }
}
 
int main(int argc, char **argv)
{
    int sockfd, len;
    struct sockaddr_in dest;
    char buffer[MAXBUF + 1];
    SSL_CTX *ctx;
    SSL *ssl;
 
    if (argc != 3)
    {
        printf("please use command:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s 127.0.0.1 8081\n", argv[0]);
        exit(0);
    }
 
 
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) 
    {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
 
 
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    {
        perror("Socket");
        exit(errno);
    }
    printf("socket created\n");
 
 
    bzero(&dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(atoi(argv[2]));
    if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0)
    {
        perror(argv[1]);
        exit(errno);
    }
    printf("address created\n");
 
 
    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0)
    {
        perror("Connect ");
        exit(errno);
    }
    printf("server connected\n");
 
 
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sockfd);
 
    if (SSL_connect(ssl) == -1)
    {
        ERR_print_errors_fp(stderr);
    }
    else
    {
        printf("Connected with {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s encryption\n", SSL_get_cipher(ssl));
        ShowCerts(ssl);
    }
 
 
    bzero(buffer, MAXBUF + 1);
 
    len = SSL_read(ssl, buffer, MAXBUF);
    if (len > 0)
    {
        printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s:{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d\n", buffer, len);
    }
    else
    {
        printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s'\n", errno, strerror(errno));
        goto finish;
    }
    bzero(buffer, MAXBUF + 1);
    strcpy(buffer, "hello this is client.");
 
    len = SSL_write(ssl, buffer, strlen(buffer));
    if (len < 0)
    {
        printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d,{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s\n", buffer, errno, strerror(errno));
    }
    else
    {
        //printf("{b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}s, {b75a474a571334bb08f4db31fa80d7688c6401b1dcf97fb55e06ed241b59472c}d\n", buffer, len);
    }
 
finish:
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
}

编译命令:

gcc -Wall -lssl server.cpp -lstdc++ -o server
gcc -Wall -lssl client.cpp -lstdc++ -o client

执行:

./server cacert.pem  privkey.pem
./client 127.0.0.1 8081

OK,这样就能建立连接发送数据了。

本文摘录于海阔天空的博客,作者: zjg555543,发布时间: 2015-07-04

相关文章

  • ssl 编程服务器和客户端完整demo c++版

    ssl 编程服务器和客户端完整demo c++版,编译环境:cent os 64, g++ 安装openssl:...

  • openssl制作免费SSL证书

    SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL...

  • Netty笔记之三:Netty实现Socket编程

    netty实现Tcp Socket编程。 demo实现功能客户端向服务端发送消息,服务器接收到消息后向客户端响应。...

  • HTTP

    HTTPS:HTTP+SSL(证书)端口:443通讯方式:客户端发送HTTP给服务器,服务器返回SSL给客户端,以...

  • 如何申请阿里云免费SSL证书利用HTTPS建站?

    什么是SSL证书? SSL(Secure Sockets Layer)是一种用于在服务器端和客户端之间建立加密连接...

  • 如何给自己企业网站申请EV SSL数字证书

    SSL证书是数字证书的一种,SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure s...

  • python 百天学习之十四天 :TCP/UDP 服务器和客户端

    练习1:TCP 服务器/客户端编程 TCP 服务端 TCP 客户端 练习2:UDP 服务器/客户端编程 UDP 服...

  • SSL

    SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道。 该安全协议主要用来提供对用户和服务器的认证...

  • SSL协议

    ① 客户端的浏览器向服务器传送客户端 SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之...

  • HTTPS加密

    OpenSSL 证书、签名服务器、证书颁发者、客户端生成私钥和公钥客户端的公钥放在了哪里? SSL、TLS 生成会...

网友评论

      本文标题:ssl 编程服务器和客户端完整demo c++版

      本文链接:https://www.haomeiwen.com/subject/ncfgoltx.html