Linux网络编程一步一步学-利用OpenSSL提供的SSL操作函数进行加密通讯原始例子

首先,大家知道SSL这一目前“事实上的Internet加密标准”吧?一般的网站是没有用到SSL的,所以如果你用TCPDUMP就可以很容易地看到别人上网的帐号、密码之类的,当然,现在有些已经改用安全通讯方式进行验证了,比如google的邮件服务gmail,而象银行、证券等行业,从一开始就要求用加密通讯,你在哪个银行网站上输入帐号和密码后点击提交不是通过加密方式提交的呢?事实上,SSL也正是在银行这些行业的需求下才产生的。
现在大家经常上网会上到一些https://开头的网站,那就是把SSL标准应用到HTTP上从而变成了HTTPS。另外大家可能都不用telnet这个明文传输工具来进行远程登录了,都改用ssh了,ssh正是SSL的一个实现,用来进行远程加密通讯的。

其次,要在我们现有的TCP程序上加上SSL,你得安装开发包libssl-dev,这个包的描述是这样的:

Package: libssl-dev
Priority: optional
Section: libdevel
Installed-Size: 5552
Maintainer: Debian OpenSSL Team
Architecture: i386
Source: openssl
Version: 0.9.8a-7ubuntu0.3
Depends: libssl0.9.8 (= 0.9.8a-7ubuntu0.3), zlib1g-dev
Conflicts: ssleay (<< 0.9.2b), libssl08-dev, libssl09-dev, libssl095a-dev, libssl096-dev
Filename: pool/main/o/openssl/libssl-dev_0.9.8a-7ubuntu0.3_i386.deb
Size: 2023440
MD5sum: 3c4052d07abe7d7984a774ca815ba4cf
SHA1: 29145b66372613e78c37d9ce0de6a7d1cfc7bac0
SHA256: 9e86aa1174a45e4f61e5afcb56d485ea60f90e31b0ecaf2bf31f426f7eb8c6eb
Description: SSL development libraries, header files and documentation
libssl and libcrypt development libraries, header files and manpages
.
It is part of the OpenSSL implementation of SSL.
Bugs: mailto:ubuntu-users@lists.ubuntu.com
Origin: Ubuntu

Package: libssl-dev
Priority: optional
Section: libdevel
Installed-Size: 5548
Maintainer: Debian OpenSSL Team
Architecture: i386
Source: openssl
Version: 0.9.8a-7build1
Depends: libssl0.9.8 (= 0.9.8a-7build1), zlib1g-dev
Conflicts: ssleay (<< 0.9.2b), libssl08-dev, libssl09-dev, libssl095a-dev, libssl096-dev
Filename: pool/main/o/openssl/libssl-dev_0.9.8a-7build1_i386.deb
Size: 2022142
MD5sum: c9b989aebbae4f6f5dbde67207858023
Description: SSL development libraries, header files and documentation
libssl and libcrypt development libraries, header files and manpages
.
It is part of the OpenSSL implementation of SSL.
Bugs: mailto:ubuntu-users@lists.ubuntu.com
Origin: Ubuntu

也就是说这个libssl-dev包是库函数、头文件以及相关编程说明文档的集合。

安装完成之后在/usr/share/doc/libssl-dev/demos目录下有一些编程示例。你可以参照里面的文档自己来写加密通讯程序。

比如/usr/share/doc/libssl-dev/demos/bio目录下提供的一个服务器端例子,代码如下:
  1. /* NOCW */
  2. /* demos/bio/saccept.c */
  3. /* A minimal program to server an SSL connection.
  4.  * It uses blocking.
  5.  * saccept host:port
  6.  * host is the interface IP to use.  If any interface, use *:port
  7.  * The default it *:4433
  8.  *
  9.  * cc -I../../include saccept.c -L../.. -lssl -lcrypto
  10.  */
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include <openssl/err.h>
  14. #include <openssl/ssl.h>
  15. #define CERT_FILE    "server.pem"
  16. BIO *in=NULL;
  17. void close_up()
  18.     {
  19.     if (in != NULL)
  20.         BIO_free(in);
  21.     }
  22. int main(argc,argv)
  23. int argc;
  24. char *argv[];
  25.     {
  26.     char *port=NULL;
  27.     BIO *ssl_bio,*tmp;
  28.     SSL_CTX *ctx;
  29.     SSL *ssl;
  30.     char buf[512];
  31.     int ret=1,i;
  32.         if (argc <= 1)
  33.         port="*:4433";
  34.     else
  35.         port=argv[1];
  36.     signal(SIGINT,close_up);
  37.     SSL_load_error_strings();
  38. #ifdef WATT32
  39.     dbug_init();
  40.     sock_init();
  41. #endif
  42.     /* Add ciphers and message digests */
  43.     OpenSSL_add_ssl_algorithms();
  44.     ctx=SSL_CTX_new(SSLv23_server_method());
  45.     if (!SSL_CTX_use_certificate_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
  46.         goto err;
  47.     if (!SSL_CTX_use_PrivateKey_file(ctx,CERT_FILE,SSL_FILETYPE_PEM))
  48.         goto err;
  49.     if (!SSL_CTX_check_private_key(ctx))
  50.         goto err;
  51.     /* Setup server side SSL bio */
  52.     ssl=SSL_new(ctx);
  53.     ssl_bio=BIO_new_ssl(ctx,0);
  54.     if ((in=BIO_new_accept(port)) == NULL) goto err;
  55.     /* This means that when a new connection is acceptede on 'in',
  56.      * The ssl_bio will be 'dupilcated' and have the new socket
  57.      * BIO push into it.  Basically it means the SSL BIO will be
  58.      * automatically setup */
  59.     BIO_set_accept_bios(in,ssl_bio);
  60. again:
  61.     /* The first call will setup the accept socket, and the second
  62.      * will get a socket.  In this loop, the first actual accept
  63.      * will occur in the BIO_read() function. */
  64.     if (BIO_do_accept(in) <= 0) goto err;
  65.     for (;;)
  66.         {
  67.         i=BIO_read(in,buf,512);
  68.         if (i == 0)
  69.             {
  70.             /* If we have finished, remove the underlying
  71.              * BIO stack so the next time we call any function
  72.              * for this BIO, it will attempt to do an
  73.              * accept */
  74.             printf("Done/n");
  75.             tmp=BIO_pop(in);
  76.             BIO_free_all(tmp);
  77.             goto again;
  78.             }
  79.         if (i < 0) goto err;
  80.         fwrite(buf,1,i,stdout);
  81.         fflush(stdout);
  82.         }
  83.     ret=0;
  84. err:
  85.     if (ret)
  86.         {
  87.         ERR_print_errors_fp(stderr);
  88.         }
  89.     if (in != NULL) BIO_free(in);
  90.     exit(ret);
  91.     return(!ret);
  92.     }

 

对应的一个客户端例子代码如下:

  1. /* NOCW */
  2. /* demos/bio/sconnect.c */
  3. /* A minimal program to do SSL to a passed host and port.
  4.  * It is actually using non-blocking IO but in a very simple manner
  5.  * sconnect host:port - it does a 'GET / HTTP/1.0'
  6.  *
  7.  * cc -I../../include sconnect.c -L../.. -lssl -lcrypto
  8.  */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <openssl/err.h>
  13. #include <openssl/ssl.h>
  14. extern int errno;
  15. int main(argc,argv)
  16. int argc;
  17. char *argv[];
  18.     {
  19.     char *host;
  20.     BIO *out;
  21.     char buf[1024*10],*p;
  22.     SSL_CTX *ssl_ctx=NULL;
  23.     SSL *ssl;
  24.     BIO *ssl_bio;
  25.     int i,len,off,ret=1;
  26.     if (argc <= 1)
  27.         host="localhost:4433";
  28.     else
  29.         host=argv[1];
  30. #ifdef WATT32
  31.     dbug_init();
  32.     sock_init();
  33. #endif
  34.     /* Lets get nice error messages */
  35.     SSL_load_error_strings();
  36.     /* Setup all the global SSL stuff */
  37.     OpenSSL_add_ssl_algorithms();
  38.     ssl_ctx=SSL_CTX_new(SSLv23_client_method());
  39.     /* Lets make a SSL structure */
  40.     ssl=SSL_new(ssl_ctx);
  41.     SSL_set_connect_state(ssl);
  42.     /* Use it inside an SSL BIO */
  43.     ssl_bio=BIO_new(BIO_f_ssl());
  44.     BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
  45.     /* Lets use a connect BIO under the SSL BIO */
  46.     out=BIO_new(BIO_s_connect());
  47.     BIO_set_conn_hostname(out,host);
  48.     BIO_set_nbio(out,1);
  49.     out=BIO_push(ssl_bio,out);
  50.     p="GET / HTTP/1.0/r/n/r/n";
  51.     len=strlen(p);
  52.     off=0;
  53.     for (;;)
  54.         {
  55.         i=BIO_write(out,&(p[off]),len);
  56.         if (i <= 0)
  57.             {
  58.             if (BIO_should_retry(out))
  59.                 {
  60.                 fprintf(stderr,"write DELAY/n");
  61.                 sleep(1);
  62.                 continue;
  63.                 }
  64.             else
  65.                 {
  66.                 goto err;
  67.                 }
  68.             }
  69.         off+=i;
  70.         len-=i;
  71.         if (len <= 0) break;
  72.         }
  73.     for (;;)
  74.         {
  75.         i=BIO_read(out,buf,sizeof(buf));
  76.         if (i == 0) break;
  77.         if (i < 0)
  78.             {
  79.             if (BIO_should_retry(out))
  80.                 {
  81.                 fprintf(stderr,"read DELAY/n");
  82.                 sleep(1);
  83.                 continue;
  84.                 }
  85.             goto err;
  86.             }
  87.         fwrite(buf,1,i,stdout);
  88.         }
  89.     ret=1;
  90.     if (0)
  91.         {
  92. err:
  93.         if (ERR_peek_error() == 0) /* system call error */
  94.             {
  95.             fprintf(stderr,"errno=%d ",errno);
  96.             perror("error");
  97.             }
  98.         else
  99.             ERR_print_errors_fp(stderr);
  100.         }
  101.     BIO_free_all(out);
  102.     if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx);
  103.     exit(!ret);
  104.     return(ret);
  105.     }

 

编译程序里象一般的gcc命令一样,但需要链接ssl库,比如

gcc -Wall saccept.c -o sslserver -lssl
gcc -Wall sconnect.c -o sslclient -l ssl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值