日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下的OpenSSL编程

發布時間:2024/9/5 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下的OpenSSL编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://www.linuxidc.com/Linux/2011-04/34523p2.htm



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 7838

有個錯誤,就是在第5部分-程序運行方式中,服務端的運行原來寫的是:

./ssl_server 7838 1 CAcert.pem privkey.pem

其實應該是:

./ssl_server 7838 1 privkey.pem privkey.pem

因為這兩個一個是服務端的證書,一個是服務端的密鑰,與CA無關,又因為pem文件包含了證書和密鑰,所以兩個地方都可以用服務端的pem文件。


總結

以上是生活随笔為你收集整理的Linux下的OpenSSL编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。