linux openssl 编程

OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。SSL是Secure Socket Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

服务器端OpenSSL编程流程:

1.SSL库初始化:SSL_library_init();

2.加载SSL算法:OpenSSL_add_all_altorithms();

3.加载错误信息:SSL_load_error_strings();

4.创建会话环境:SSL_CTX_new();

5.加载用户证书:SSL_CTX_use_certificate_file();

6.加载用户私钥:SSL_CTX_PrivateKey_file();

7.检查用户证书私钥是否匹配:SSL_CTX_check_private_key();

8.创建socket();

9.bind(sockfd);

10.listen(sockfd,maxconnect);

11.accept(sockfd,...);

12.创建新的ssl:SSL_new();

13.accetpfd

14.建立ssl连接:ssl_accept

15.SSL_read();

16.SSL_write();

17.SSL_shutdown(),SSL_free(),SSL_CTX_free();

客户端OpenSSL编程流程:

1.SSL库初始化:SSL_library_init();

2.加载SSL算法:OpenSSL_add_all_altorithms();

3.加载错误信息:SSL_load_error_strings();

4.创建会话环境:SSL_CTX_new();

5.加载用户证书:SSL_CTX_use_certificate_file();

6.加载用户私钥:SSL_CTX_PrivateKey_file();

7.检查用户证书私钥是否匹配:SSL_CTX_check_private_key();

8.创建socket();

9.connect();

10.创建新的ssl:SSL_new();

11.加入ssl,SSL_set_fd

12.创建SSL_connect();

13.SSL_write();

14.SSL_read();

15.SSL_shutdown(),SSL_free(),SSL_CTX_free();

服务器端代码:

#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.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>
#include <curses.h>

#define MAXSIZE 1024
#define PORT 6666
int main()
{
    int err;
    char recvbuf[MAXSIZE];
    int sockfd,acceptfd;
    int bindnes;
    struct sockaddr_in server_addr,client_addr;
    SSL_CTX *ctx;
    SSL *ssl;
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_server_method());
    if(ctx == NULL)
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
    SSL_CTX_load_verify_locations(ctx,"./openssl/ca.crt",NULL);
    if(0 == SSL_CTX_use_certificate_file(ctx,"./openssl/server.crt",SSL_FILETYPE_PEM))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    if(0 == SSL_CTX_use_PrivateKey_file(ctx,"./openssl/server.key",SSL_FILETYPE_PEM))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    if(!SSL_CTX_check_private_key(ctx))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd <= 0)
    {
        printf("socket error:%s\n",strerror(errno));
        exit(1);
    }
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(PORT);
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    bindnes = bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
    if(bindnes == -1 )
    {
        printf("bind error:%s\n",strerror(errno));
        exit(1);
    }
    listen(sockfd,10);
    socklen_t len = sizeof(client_addr);
    acceptfd=accept(sockfd,(struct sockaddr*)&client_addr,&len);
    ssl = SSL_new(ctx);
    if(ssl == NULL)
    {
        printf("error:%s:ssl is null",strerror(errno));
        exit(1);
    }
    if(0 == SSL_set_fd(ssl,acceptfd))
    {
        printf("socket add to SSL error:%s\n",strerror(errno));
        exit(1);
    }
    int k = SSL_accept(ssl);
    if(k <= 0)
    {
        printf("connect fail:%s\n",strerror(errno));
        exit(1);
    }
    X509 *client_crt;
    client_crt = SSL_get_peer_certificate(ssl);
    printf("find a client try to connect !\n");
    while(1)
    {
        err = SSL_read(ssl,recvbuf,sizeof(recvbuf));
        printf("data of buf :%d\n",err);
        if(err == 0)
        {
            printf("client had disconnected\n");
            exit(1);
        }
        recvbuf[err] = '\0';
        printf("recvbuf:%s\n",recvbuf);
    }
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    close(acceptfd);
    return 0;
}
客户端代码:

#include <stdio.h>
#include <string.h>
#include <errno.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>
#include <errno.h>
#include <curses.h>
#include <openssl/rand.h>

#define MAXSIZE 1024
#define PORT  6666
int main()
{
    SSL *ssl;
    int sockfd;
    char sendbuf[MAXSIZE];
    SSL_CTX *ctx;
    struct sockaddr_in addr;
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_client_method());
    if(ctx == NULL)
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    SSL_CTX_load_verify_locations(ctx,"./openssl/ca.crt",NULL);
    if(0 == SSL_CTX_use_certificate_file(ctx,"./openssl/client.crt",SSL_FILETYPE_PEM))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    if(0 == SSL_CTX_use_PrivateKey_file(ctx,"./openssl/client.key",SSL_FILETYPE_PEM))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    if(!SSL_CTX_check_private_key(ctx))
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd <= 0)
    {
        printf("socket error:%s\n",strerror(errno));
        exit(1);
    }
    memset(&addr,0,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(PORT);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    if(connect(sockfd,(struct sockaddr*)&addr,sizeof(addr)) < 0)
    {
        printf("connect error:%s\n",strerror(errno));
        exit(1);
    }
    ssl = SSL_new(ctx);
    if(NULL == ssl)
    {
        printf("error:%s\n",strerror(errno));
        exit(1);
    }
    if(SSL_set_fd(ssl,sockfd) <= 0)
    {
        printf("add ssl error:%s\n",strerror(errno));
        exit(1);
    }
    int k = SSL_connect(ssl);
    if(k == 0)
    {
        printf("connect error:%s\n",strerror(errno));
        exit(1);
    }
    while(1)
    {
        printf("input the data to send:\n");
        scanf("%s",sendbuf);
        SSL_write(ssl,sendbuf,strlen(sendbuf));
        printf("send msg:%s success\n",sendbuf);
    }
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章