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;
}
 

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