linux ssl例子_linux 配置ssl ssl on;开启 就报错 - CSDN
  • 1.安装openssl库:  sudo sudo apt-get install libssl-dev 2.服务器端实现代码 #include stdio.h> #include stdlib.h> #include errno.h> #include string.h> ...#include netinet/in.h>
    1.安装openssl库:
      sudo sudo apt-get install libssl-dev
    2.服务器端实现代码

    #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

    int main(int argc, char **argv)
    {
        int sockfd, new_fd;
        socklen_t len;
        struct sockaddr_in my_addr, their_addr;
        unsigned int myport, lisnum;
        char buf[MAXBUF + 1];
        SSL_CTX *ctx;

        if (argv[1])
            myport = atoi(argv[1]);
        else
            myport = 7838;

        if (argv[2])
            lisnum = atoi(argv[2]);
        else
            lisnum = 2;

        /* SSL 库初始化 */
        SSL_library_init();
        /* 载入所有 SSL 算法 */
        OpenSSL_add_all_algorithms();
        /* 载入所有 SSL 错误消息 */
        SSL_load_error_strings();
        /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */
        ctx = SSL_CTX_new(SSLv23_server_method());
        /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */
        if (ctx == NULL) {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
        if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        /* 载入用户私钥 */
        if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0){
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        /* 检查用户私钥是否正确 */
        if (!SSL_CTX_check_private_key(ctx)) {
            ERR_print_errors_fp(stdout);
            exit(1);
        }

        /* 开启一个 socket 监听 */
        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
            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(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");

        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 %s, port %d, socket %d\n",
                       inet_ntoa(their_addr.sin_addr),
                       ntohs(their_addr.sin_port), new_fd);

            /* 基于 ctx 产生一个新的 SSL */
            ssl = SSL_new(ctx);
            /* 将连接用户的 socket 加入到 SSL */
            SSL_set_fd(ssl, new_fd);
            /* 建立 SSL 连接 */
            if (SSL_accept(ssl) == -1) {
                perror("accept");
                close(new_fd);
                break;
            }

            /* 开始处理每个新连接上的数据收发 */
            bzero(buf, MAXBUF + 1);
            strcpy(buf, "server->client");
            /* 发消息给客户端 */
            len = SSL_write(ssl, buf, strlen(buf));

            if (len <= 0) {
                printf
                    ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
                     buf, errno, strerror(errno));
                goto finish;
            } else
                printf("消息'%s'发送成功,共发送了%d个字节!\n",
                       buf, len);

            bzero(buf, MAXBUF + 1);
            /* 接收客户端的消息 */
            len = SSL_read(ssl, buf, MAXBUF);
            if (len > 0)
                printf("接收消息成功:'%s',共%d个字节的数据\n",
                       buf, len);
            else
                printf
                    ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
                     errno, strerror(errno));
            /* 处理每个新连接上的数据收发结束 */
          finish:
            /* 关闭 SSL 连接 */
            SSL_shutdown(ssl);
            /* 释放 SSL */
            SSL_free(ssl);
            /* 关闭 socket */
            close(new_fd);
        }
        /* 关闭监听的 socket */
        close(sockfd);
        /* 释放 CTX */
        SSL_CTX_free(ctx);
        return 0;
    }


    2. 客户端实现代码

    dfa

    #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("数字证书信息:\n");
            line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
            printf("证书: %s\n", line);
            free(line);
            line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
            printf("颁发者: %s\n", line);
            free(line);
            X509_free(cert);
        } else
            printf("无证书信息!\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("参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个"
                 "IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
                 argv[0], argv[0]);
            exit(0);
        }

        /* SSL 库初始化,参看 ssl-server.c 代码 */
        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);
        }

        /* 创建一个 socket 用于 tcp 通信 */
        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");

        /* 基于 ctx 产生一个新的 SSL */
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, sockfd);
        /* 建立 SSL 连接 */
        if (SSL_connect(ssl) == -1)
            ERR_print_errors_fp(stderr);
        else {
            printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
            ShowCerts(ssl);
        }

        /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
        bzero(buffer, MAXBUF + 1);
        /* 接收服务器来的消息 */
        len = SSL_read(ssl, buffer, MAXBUF);
        if (len > 0)
            printf("接收消息成功:'%s',共%d个字节的数据\n",
                   buffer, len);
        else {
            printf
                ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
                 errno, strerror(errno));
            goto finish;
        }
        bzero(buffer, MAXBUF + 1);
        strcpy(buffer, "from client->server");
        /* 发消息给服务器 */
        len = SSL_write(ssl, buffer, strlen(buffer));
        if (len < 0)
            printf
                ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
                 buffer, errno, strerror(errno));
        else
            printf("消息'%s'发送成功,共发送了%d个字节!\n",
                   buffer, len);

      finish:
        /* 关闭连接 */
        SSL_shutdown(ssl);
        SSL_free(ssl);
        close(sockfd);
        SSL_CTX_free(ctx);
        return 0;
    }


    3. 编译方式:
    gcc -o ssl_server ssl_server.c -Wall -g -lssl
    gcc -o ssl_client ssl_client.c -Wall -g -lssl

    4. 生产私钥和证书
    openssl genrsa -out privkey.pem 1024
    openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095

    5. 程序运行方式:
    ./ssl_server 7838 1 CAcert.pem privkey.pem
    ./ssl_client 127.0.0.1 7838linux
    展开全文
  • Linux下socket ssl编程

    2016-04-20 15:22:42
    转自:... 编译程序用下列命令: gcc -Wall ssl-client.c -o client gcc -Wall ssl-server.c -o server 运行程序用如下命令: ./server 7838 1 cacert.pem privkey.pem ./client 127.0.0.1 78

    转自:http://www.tootoogo.org/wordpress/?p=611

    编译程序用下列命令:
    gcc -Wall ssl-client.c -o client
    gcc -Wall ssl-server.c -o server
    运行程序用如下命令:
    ./server 7838 1 cacert.pem privkey.pem
    ./client 127.0.0.1 7838

    用下面这两个命令产生上述cacert.pem和privkey.pem文件:
    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
    /************关于本文档********************************************
    *filename: ssl-server.c
    *purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是服务器端例子
    *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
    Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
    *date time:2007-02-02 19:40
    *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
    * 但请遵循GPL
    *Thanks to:Google
    *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
    * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
    *********************************************************************/
    int main(int argc, char **argv)
    {
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    char buf[MAXBUF + 1];
    SSL_CTX *ctx;

    if (argv[1])
    myport = atoi(argv[1]);
    else
    myport = 7838;

    if (argv[2])
    lisnum = atoi(argv[2]);
    else
    lisnum = 2;

    /* SSL 库初始化 */
    SSL_library_init();
    /* 载入所有 SSL 算法 */
    OpenSSL_add_all_algorithms();
    /* 载入所有 SSL 错误消息 */
    SSL_load_error_strings();
    /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */
    ctx = SSL_CTX_new(SSLv23_server_method());
    /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */
    if (ctx == NULL) {
    ERR_print_errors_fp(stdout);
    exit(1);
    }
    /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
    if (SSL_CTX_use_certificate_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stdout);
    exit(1);
    }
    /* 载入用户私钥 */
    if (SSL_CTX_use_PrivateKey_file(ctx, argv[5], SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stdout);
    exit(1);
    }
    /* 检查用户私钥是否正确 */
    if (!SSL_CTX_check_private_key(ctx)) {
    ERR_print_errors_fp(stdout);
    exit(1);
    }

    /* 开启一个 socket 监听 */
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
    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(myport);
    if (argv[3])
    my_addr.sin_addr.s_addr = inet_addr(argv[3]);
    else
    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");

    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 %s, port %d, socket %d\n",
    inet_ntoa(their_addr.sin_addr),
    ntohs(their_addr.sin_port), new_fd);

    /* 基于 ctx 产生一个新的 SSL */
    ssl = SSL_new(ctx);
    /* 将连接用户的 socket 加入到 SSL */
    SSL_set_fd(ssl, new_fd);
    /* 建立 SSL 连接 */
    if (SSL_accept(ssl) == -1) {
    perror("accept");
    close(new_fd);
    break;
    }

    /* 开始处理每个新连接上的数据收发 */
    bzero(buf, MAXBUF + 1);
    strcpy(buf, "server->client");
    /* 发消息给客户端 */
    len = SSL_write(ssl, buf, strlen(buf));

    if (len <= 0) {
    printf
    ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
    buf, errno, strerror(errno));
    goto finish;
    } else
    printf("消息'%s'发送成功,共发送了%d个字节!\n",
    buf, len);

    bzero(buf, MAXBUF + 1);
    /* 接收客户端的消息 */
    len = SSL_read(ssl, buf, MAXBUF);
    if (len > 0)
    printf("接收消息成功:'%s',共%d个字节的数据\n",
    buf, len);
    else
    printf
    ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
    errno, strerror(errno));
    /* 处理每个新连接上的数据收发结束 */
    finish:
    /* 关闭 SSL 连接 */
    SSL_shutdown(ssl);
    /* 释放 SSL */
    SSL_free(ssl);
    /* 关闭 socket */
    close(new_fd);
    }

    /* 关闭监听的 socket */
    close(sockfd);
    /* 释放 CTX */
    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("数字证书信息:\n");
    line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
    printf("证书: %s\n", line);
    free(line);
    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
    printf("颁发者: %s\n", line);
    free(line);
    X509_free(cert);
    } else
    printf("无证书信息!\n");
    }
    /************关于本文档********************************************
    *filename: ssl-client.c
    *purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是客户端例子
    *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
    Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
    *date time:2007-02-02 20:10
    *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
    * 但请遵循GPL
    *Thanks to:Google
    *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
    * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
    *********************************************************************/
    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
    ("参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
    argv[0], argv[0]);
    exit(0);
    }

    /* SSL 库初始化,参看 ssl-server.c 代码 */
    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);
    }

    /* 创建一个 socket 用于 tcp 通信 */
    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");

    /* 基于 ctx 产生一个新的 SSL */
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sockfd);
    /* 建立 SSL 连接 */
    if (SSL_connect(ssl) == -1)
    ERR_print_errors_fp(stderr);
    else {
    printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
    ShowCerts(ssl);
    }

    /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
    bzero(buffer, MAXBUF + 1);
    /* 接收服务器来的消息 */
    len = SSL_read(ssl, buffer, MAXBUF);
    if (len > 0)
    printf("接收消息成功:'%s',共%d个字节的数据\n",
    buffer, len);
    else {
    printf
    ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
    errno, strerror(errno));
    goto finish;
    }
    bzero(buffer, MAXBUF + 1);
    strcpy(buffer, "from client->server");
    /* 发消息给服务器 */
    len = SSL_write(ssl, buffer, strlen(buffer));
    if (len < 0)
    printf
    ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
    buffer, errno, strerror(errno));
    else
    printf("消息'%s'发送成功,共发送了%d个字节!\n",
    buffer, len);

    finish:
    /* 关闭连接 */
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
    }

    展开全文
  • SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。安全证书既包含了用于加密...

    更新:修改了源码,在ubuntu16.04+OpenSSL 1.0.2环境下编译通过。
    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。

    安全证书既包含了用于加密数据的密钥,又包含了用于证实身份的数字签名。安全证书采用公钥加密技术。公钥加密是指使用一对非对称的密钥进行加密或解密。每一对密钥由公钥和私钥组成。公钥被广泛发布。私钥是隐秘的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能被公钥解密。这个非对称的特性使得公钥加密很有用。在安全证书中包含着一对非对称的密钥。只有安全证书的所有者才知道私钥。当通信方A将自己的安全证书发送给通信方B时,实际上发给通信方B的是公开密钥,接着通信方B可以向通信方A发送用公钥加密的数据,只有通信方A才能使用私钥对数据进行解密,从而获得通信方B发送的原始数据。安全证书中的数字签名部分是通信方A的电子身份证。数字签名告诉通信方B该信息确实由通信方A发出,不是伪造的,也没有被篡改。

    客户与服务器通信时,首先要进行SSL握手,SSL握手主要完成以下任务:

    1)协商使用的加密套件。加密套件中包括一组加密参数,这些参数指定了加密算法和密钥的长度等信息。

    2)验证对方的身份,此操作是可选的。

    3)确定使用的加密算法。

    4)SSL握手过程采用非对称加密方法传递数据,由此来建立一个安全的SSL会话。SSL握手完成后,通信双方将采用对称加密方法传递实际的应用数据。

    以下是SSL握手的具体流程:

    (1)客户将自己的SSL版本号、加密参数、与SSL会话有关的数据及其他一些必要信息发送到服务器。

    (2)服务器将自己的SSL版本号、加密参数、与SSL会话有关的数据及其他一些必要信息发送给客户,同时发给客户的还有服务器的证书。如果服务器需要验证客户身份,服务器还会发出要求客户提供安全证书的请求。

    (3)客户端验证服务器证书,如果验证失败,就提示不能建立SSL连接。如果成功,那么继续下一步骤。

    (4)客户端为本次SSL会话生成预备主密码(pre-master secret),并将其用服务器公钥加密后发送给服务器。

    (5)如果服务器要求验证客户身份,客户端还要对另外一些数据签名后,将其与客户端证书一起发送给服务器。

    (6)如果服务器要求验证客户身份,则检查签署客户证书的CA(Certificate Authority,证书机构)是否可信。如果不在信任列表中,结束本次会话。如果检查通过,服务器用自己的私钥解密收到的预备主密码(pre-master secret),并用它通过某些算法生成本次会话的主密码(master secret)。

    (7)客户端与服务器端均使用此主密码(master secret)生成此次会话的会话密钥(对称密钥)。在双方SSL握手结束后传递任何消息均使用此会话密钥。这样做的主要原因是对称加密比非对称加密的运算量要低一个数量级以上,能够显著提高双方会话时的运算速度。

    (8)客户端通知服务器此后发送的消息都使用这个会话密钥进行加密,并通知服务器客户端已经完成本次SSL握手。

    (9)服务器通知客户端此后发送的消息都使用这个会话密钥进行加密,并通知客户端服务器已经完成本次SSL握手。

    (10)本次握手过程结束,SSL会话已经建立。在接下来的会话过程中,双方使用同一个会话密钥分别对发送和接收的信息进行加密和解密。

    以下为 linux c/c++ SSL socket Client和Server的代码参考。

    客户端代码如下:

    #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 )
    
    {
    
        printf("Eroor: %s\n",hostname);
    
        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 = SSLv2_client_method(); /* Create new client-method instance */
    
    ctx = SSL_CTX_new(method);  /* Create new context */
    
    if( ctx == NULL )
    
    {
    
        ERR_print_errors_fp(stderr);
    
        printf("Eroor: %s\n",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("No certificates.\n");
    
    }
    
    int main(int count,char*strings[])
    
    {   SSL_CTX *ctx;
    
    int server;
    
    SSL *ssl;
    
    char buf[1024];
    
    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();
    
    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 */
    
    {
    
        printf("Eroor: %s\n",stderr);
    
        ERR_print_errors_fp(stderr);
    
    }
    
    else
    
    {  char*msg ="HelloWorld";
    
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
    
        ShowCerts(ssl);       /* get any certs */
    
        SSL_write(ssl, msg,strlen(msg));  /* encrypt & send message */
    
        bytes = SSL_read(ssl, buf,sizeof(buf));/* get reply & decrypt */
    
        buf[bytes] = 0;
    
        printf("Received: \"%s\"\n", buf);
    
        SSL_free(ssl);       /* release connection state */
    
    }
    
    close(server);        /* close socket */
    
    SSL_CTX_free(ctx);       /* release context */
    
    return 0;
    
    }
    

    服务端代码如下:

    #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"
    
    #define FAIL    -1
    
    usingnamespacestd;
    
    intOpenListener(intport)
    
    {  intsd;
    
    structsockaddr_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, (structsockaddr*)&addr,sizeof(addr)) != 0 )
    
    {
    
        perror("can't bind port");
    
        abort();
    
    }
    
    if( listen(sd, 10) != 0 )
    
    {
    
        perror("Can't configure listening port");
    
        abort();
    
    }
    
    returnsd;
    
    }
    
    SSL_CTX* InitServerCTX(void)
    
    {
    
    SSL_CTX *ctx = NULL;
    
        #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    
               constSSL_METHOD *method;
    
        #else
    
                SSL_METHOD *method;
    
        #endif
    
        SSL_library_init();
    
        OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
    
        SSL_load_error_strings();  /* load all error messages */
    
        method = SSLv23_client_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();
    
        }
    
        returnctx;
    
    }
    
    voidLoadCertificates(SSL_CTX* ctx,char* CertFile,char* KeyFile)
    
    {
    
    //New lines
    
        if(SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
    
            ERR_print_errors_fp(stderr);
    
        if(SSL_CTX_set_default_verify_paths(ctx) != 1)
    
            ERR_print_errors_fp(stderr);
    
        //End new lines
    
    /* 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();
    
    }
    
    printf("LoadCertificates Compleate Successfully.....\n");
    
    }
    
    voidShowCerts(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");
    
    }
    
    voidServlet(SSL* ssl)/* Serve the connection -- threadable */
    
    {  charbuf[1024];
    
    charreply[1024];
    
    intsd, bytes;
    
    constchar* HTMLecho="<html><body><pre>%s</pre></body></html>\n\n";
    
    if( SSL_accept(ssl) == FAIL )    /* do SSL-protocol accept */
    
        ERR_print_errors_fp(stderr);
    
    else
    
    {
    
        ShowCerts(ssl);       /* get any certificates */
    
        bytes = SSL_read(ssl, buf,sizeof(buf));/* get request */
    
        if( bytes > 0 )
    
        {
    
            buf[bytes] = 0;
    
            printf("Client msg: \"%s\"\n", buf);
    
            sprintf(reply, HTMLecho, buf);  /* construct reply */
    
            SSL_write(ssl, reply,strlen(reply));/* 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 */
    
    }
    
    intmain(intcount,char*strings[])
    
    {   SSL_CTX *ctx;
    
    intserver;
    
    char*portnum;
    
    if( count != 2 )
    
    {
    
        printf("Usage: %s <portnum>\n", strings[0]);
    
        exit(0);
    
    }
    
    else
    
    {
    
        printf("Usage: %s <portnum>\n", strings[1]);
    
    }
    
    SSL_library_init();
    
    portnum = strings[1];
    
    ctx = InitServerCTX();       /* initialize SSL */
    
    LoadCertificates(ctx,"/home/stud/kawsar/mycert.pem","/home/stud/kawsar/mycert.pem"); /* load certs */
    
    server = OpenListener(atoi(portnum));   /* create server socket */
    
    while(1)
    
    {  structsockaddr_in addr;
    
        socklen_t len =sizeof(addr);
    
        SSL *ssl;
    
        intclient = accept(server, (structsockaddr*)&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 */
    
    }
    

    转自SSL握手通信详解及linux C Socket代码举例

    展开全文
  • linux下tomcat8.5.4配置ssl

    2018-07-24 10:49:56
    tomcat不同的版本对ssl的配置有所不同。8.0以下的版本网上很多,这里就不去说了。下面主要记录的就是8.5.4对ssl的配置 1.获取ssl。 我这里使用的是阿里云提供的ssl。操作步骤: ①:进入阿里云的域名管理 ②:...

    tomcat不同的版本对ssl的配置有所不同。8.0以下的版本网上很多,这里就不去说了。下面主要记录的就是8.5.4对ssl的配置

    1.获取ssl。

    我这里使用的是阿里云提供的ssl。操作步骤:

    ①:进入阿里云的域名管理

    ②:选择ssl证书,如下图

    ③:如果已经申请了ssl证书,就直接点击证书控制台。没有的可以通过购买或者申请免费证书。

    ④:选择需要的证书下载

    2.配置证书

    在上面的下载证书的页面有关于证书的配置,但是这个配置不适用于8.5.4,但是配置前面的步骤是通用的。我配置的是JKS证书

    生成jks证书之后通过命令查看证书:keytool -keystore your-name.jks -list

    显示如下

    3:配置tomcat中的server.xml文件

    这是tomcat自带的配置例子;

    修改为:

    <Connector port="端口" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" SSLEnabled="true">
            <SSLHostConfig>
                <Certificate certificateKeystoreFile="jks文件位置"
    						certificateKeystorePassword="上面步骤的密码"
    						certificateKeyAlias="上面查询出来的别名"
                             type="RSA" />
            </SSLHostConfig>
        </Connector>

    <Connector port="端口" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   maxThreads="150" SSLEnabled="true">
            <SSLHostConfig>
                <Certificate certificateKeystoreFile="jks文件位置"
                            certificateKeystorePassword="上面步骤的密码"
                            certificateKeyAlias="上面查询出来的别名"
                             type="RSA" />
            </SSLHostConfig>
        </Connector>

    4:将redirectPort的端口配置到ssl的端口上。

    5:将http的请求自动跳转到https上。

    在web.xml的末尾加上代码

     

    <security-constraint>
    
        <web-resource-collection >
    
                  <web-resource-name >SSL</web-resource-name>
    
                  <url-pattern>/*</url-pattern>
    
           </web-resource-collection>
    
           <user-data-constraint>
    
           <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    
           </user-data-constraint>
    
    </security-constraint>

    <security-constraint>     <web-resource-collection >               <web-resource-name >SSL</web-resource-name>               <url-pattern>/*</url-pattern>        </web-resource-collection>        <user-data-constraint>        <transport-guarantee>CONFIDENTIAL</transport-guarantee>        </user-data-constraint> </security-constraint>

    展开全文
  • 在工作中发现一个有用的东西,在很多公司网站广泛使用SSL,但对于我们生产系统,这意味着从广泛认可的证书颁发机构(如Verisign或Thawte)购买SSL证书,但对于我们开发系统,当有10个15个需要SSL的不同预生产环境时...
  • server.c /************关于本文档********************************************  * *filename: ssl-server.c  * *purpose: 演示利用OpenSSL 库进行基于IP ... * Linux 爱好者Linux 知识传播者SOHO 族开发者
  • http://www.yuanma.org/data/2007/1203/article_2904.htm 服务器端源代码如下: #include #include #include #include #include #include #include #include #include #include #include
  • 本程序可以自由使用,请遵守GPL规范... OpenSSL中的SSL安全通信可以分为两类,两类基本上的操作相同,一类是建立SSL环境后使用BIO读写,另一类是直接在socket上建立SSL上下文环境。本文主要讨论在socket上建立
  • 基于官网的boost.asio的HTTPS/SSL例子,包括server和client端,完整的Linux编译环境,包含了完整的boost库和openssl库,编译配置测试说明文档,测试用的server.crt和server.key证书文件。如需windows版本,和自己...
  • ssl示例和流程

    2017-10-28 13:19:02
    编译程序用下列命令: gcc -Wall ssl-client.c -o client gcc -Wall ssl-server.c -o server
  • SSL/TLS Programe In Linux一、几个名词:1. SSL(Secure Socket Layer)是Netscape公司设计的主要用于WEB的安全传输协议。这种协议在WEB上获得了广泛的应用。 2. IETF将SSL作了标准化,即RFC2246,并将其称为TLS...
  • 所谓的双向的SSL认证,打个通俗的比方就是,在进行SSL加密通信前,通信的双方(在咱们的例子中是mosquitto服务器端和MQTT客户端(消息的发送或者接收端))需要相互验证各自的证书是否合法。比如,是否是一个合法的CA...
  • 首先我们来说说 lftp ...lftp支持tab自动补全,记不得命令双击tab键,就可以看到可能的选项了。 1. 语法和常用参数 lftp(选项)(参数) #参数为要访问的站点的ip地址或者域名。...-f:指定lftp指令要执行的脚本文件;...
  • 一般的网站是没有用到SSL的,所以如果你用TCPDUMP就可以很容易地看到别人上网的帐号、密码之类的,当然,现在有些已经改用安全通讯方式进行验证了,比如google的邮件服务gmail,而象银行、证券等行业,从一开始就...
  • 该攻击利用了SSL协议renegotiation的漏洞,允许攻击者以中间人攻击的方式在通信的起始部分插入任意的选择明文。以下假设你对SSL/TLS的工作方式,尤其是renegotiation比较熟悉,并且对HTTP有基本的了解。第一个场景:...
1 2 3 4 5 ... 20
收藏数 20,784
精华内容 8,313
关键字:

linux ssl例子