精华内容
下载资源
问答
  • openssl编程
    2022-06-25 07:57:03

    一、OpenSSL 基本概念

    /index.html (openssl.org)

    OpenSSL 中文手册 | OpenSSL 中文网

    二、OpenSSL 命令学习

    1、openssl 命令

    onlylove@ubuntu:~$ openssl help
    Standard commands
    asn1parse         ca                ciphers           cms               
    crl               crl2pkcs7         dgst              dhparam           
    dsa               dsaparam          ec                ecparam           
    enc               engine            errstr            gendsa            
    genpkey           genrsa            help              list              
    nseq              ocsp              passwd            pkcs12            
    pkcs7             pkcs8             pkey              pkeyparam         
    pkeyutl           prime             rand              rehash            
    req               rsa               rsautl            s_client          
    s_server          s_time            sess_id           smime             
    speed             spkac             srp               storeutl          
    ts                verify            version           x509              
    
    Message Digest commands (see the `dgst' command for more details)
    blake2b512        blake2s256        gost              md4               
    md5               rmd160            sha1              sha224            
    sha256            sha3-224          sha3-256          sha3-384          
    sha3-512          sha384            sha512            sha512-224        
    sha512-256        shake128          shake256          sm3               
    
    Cipher commands (see the `enc' command for more details)
    aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
    aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
    aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
    aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
    aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
    aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
    aria-256-ctr      aria-256-ecb      aria-256-ofb      base64            
    bf                bf-cbc            bf-cfb            bf-ecb            
    bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  
    camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast              
    cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb         
    cast5-ofb         des               des-cbc           des-cfb           
    des-ecb           des-ede           des-ede-cbc       des-ede-cfb       
    des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
    des-ede3-ofb      des-ofb           des3              desx              
    rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc           
    rc2-cfb           rc2-ecb           rc2-ofb           rc4               
    rc4-40            seed              seed-cbc          seed-cfb          
    seed-ecb          seed-ofb          sm4-cbc           sm4-cfb           
    sm4-ctr           sm4-ecb           sm4-ofb           
    
    onlylove@ubuntu:~$
    
    命令说明
    asn1parse一种用来诊断ASN.1结构的工具,也能用于从ASN1.1数据中提取数据。
    ca一个小型CA系统。它能签发证书请求和生成CRL。它维护一个已签发证书状态的文本数据库。
    ciphers显示支持的加密套件。
    cms
    crl用于处里PME或DER格式的CRL文件。
    crl2pkcs7根据CRL或证书来生成pkcs#7消息。
    dgst用于数据摘要。
    dhparamdhparam为dh参数操作和生成工具。
    dsa用于处理DSA密钥、格式转换和打印信息。
    dsaparam用于生成和操作dsa参数。
    ec椭圆曲线密钥处理工具。
    ecparam椭圆曲线密钥参数生成及操作。
    encenc为对称加解密工具,还可以进行base64编码转换。
    engine
    errstr用于查询错误代码。
    gendsa根据DSA密钥参数生成DSA密钥,dsa密钥参数可用dsaparam命令生成。
    genpkey
    genrsa生成RSA密钥。
    help
    list
    nseq用于多个证书与netscape证书序列间相互转化。
    ocsp
    passwd生成各种口令密文。
    pkcs12pkcs12文件工具,能生成和分析pkcs12文件。
    pkcs7用于处理DER或者PEM格式的pkcs#7文件。
    pkcs8pkcs8格式的私钥转换工具。
    pkey
    pkeyparam
    pkeyutl
    prime检查一个数是否为素数。
    rand生成随机数。
    rehash
    req用于生成和处理PKCS#10证书请求。
    rsa用于处理RSA密钥、格式转换和打印信息。
    rsautl使用RSA算法签名,验证身份, 加密/解密数据。
    s_clients_client为一个SSL/TLS客户端程序,与s_server对应,它不仅能与s_server进行通信,也能与任何使用ssl协议的其他服务程序进行通信。
    s_servers_server是openssl提供的一个SSL服务程序。使用此程序前,需要生成各种证书。
    s_times_time是openss提供的SSL/TLS性能测试工具,用于测试SSL/TSL服务。
    sess_idsess_id为SSL/TLS协议的session处理工具。
    smimeS/MIME工具,用于处理S/MIME邮件,它能加密、解密、签名和验证S/MIME消息。
    speed用于测试库的性能。
    spkac
    srp
    storeutl
    ts
    verify证书验证工具。
    version用来打印版本以及openssl其他各种信息。
    x509X509命令是一个多用途的证书工具。它可以显示证书信息、转换证书格式、签名证书请求以及改变证书的信任设置等。

    2、命令格式查询

    查看命令具体用法,使用 -help 命令查看。以 ciphers 为例:

    onlylove@ubuntu:~$ openssl ciphers -help
    Usage: ciphers [options]
    Valid options are:
     -help              Display this summary
     -v                 Verbose listing of the SSL/TLS ciphers
     -V                 Even more verbose
     -s                 Only supported ciphers
     -tls1              TLS1 mode
     -tls1_1            TLS1.1 mode
     -tls1_2            TLS1.2 mode
     -tls1_3            TLS1.3 mode
     -stdname           Show standard cipher names
     -psk               include ciphersuites requiring PSK
     -srp               include ciphersuites requiring SRP
     -convert val       Convert standard name into OpenSSL name
     -ciphersuites val  Configure the TLSv1.3 ciphersuites to use
    onlylove@ubuntu:~$
    
    更多相关内容
  • OPENSSL 编程入门

    2015-08-19 13:15:34
    OpenSSL编程入门, 快速掌握OpenSSL开发安全HTTP通讯
  • openssl编程

    2015-11-15 11:12:36
    openssl编程手册,赵春平版本,喜欢的朋友可以下载,标题一定要长。
  • openSSL编程

    2021-05-27 20:32:25
    //载入ssl算法 OpenSSL_add_all_algorithms(); //载入ssl错误消息 SSL_load_error_strings(); } 2、服务端初始化 SSL_CTX *ssl_server_init(int verify_type, const char *ca, const char *user_cert, const char *...

    目录

    1、ssl服务初始化

    2、服务端初始化

    3、客户端初始化

    4、封装ssl握手函数

    5、封装SSL_read函数

    6、封装SSL_write函数

    7、demo示例

    8、总结与说明


    1、ssl服务初始化

    void ssl_service_init(void)
    {
    	//ssl库初始化
        SSL_library_init(); 
        //载入ssl算法
        OpenSSL_add_all_algorithms();
        //载入ssl错误消息
        SSL_load_error_strings();
    }

    2、服务端初始化

    SSL_CTX *ssl_server_init(int verify_type, const char *ca, const char *user_cert, const char *user_key)
    {
    	//创建SSL_CTX Content Text),兼容 ssl v2 和 v3 版本
        //SSLv2_server_method() v2, SSLv3_server_method() v3
        SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
        if (ctx == NULL) 
        {
            ERR_print_errors_fp(stderr);
            return NULL;
        }
    
        if (verify_type == SSL_VERIFY_NONE)
        {
        	//单向认证:SSL_VERIFY_NONE 不认证对方
    	 	SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);   
        }
        else if (verify_type == SSL_VERIFY_PEER)
        {
        	//双向验证
    	    //SSL_VERIFY_PEER:要求对证书进行认证,没有证书也会放行
    	    //SSL_VERIFY_FAIL_IF_NO_PEER_CERT:要求客户端需要提供证书,但验证发现单独使用没有证书也会放行
        	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
        	//设置信任根证书
    	    if (SSL_CTX_load_verify_locations(ctx, ca, NULL) <= 0)
    	    {
    	        ERR_print_errors_fp(stderr);
    	        SSL_CTX_free(ctx);
    	        return NULL;
    	    }
        }
        else
        {
        	SSL_CTX_free(ctx);
        	return NULL;
        }	
    
         //载入用户的数字证书,此证书用来发送给客户端,证书里包含有公钥
        if (SSL_CTX_use_certificate_file(ctx, user_cert, SSL_FILETYPE_PEM) <= 0) 
        {
            ERR_print_errors_fp(stderr);
            SSL_CTX_free(ctx);
            return NULL;
        }
        //载入用户私钥
        if (SSL_CTX_use_PrivateKey_file(ctx, user_key, SSL_FILETYPE_PEM) <= 0) 
        {
            ERR_print_errors_fp(stderr);
            SSL_CTX_free(ctx);
            return NULL;
        }
        //检查用户私钥是否正确
        if (!SSL_CTX_check_private_key(ctx)) 
        {
            ERR_print_errors_fp(stderr);
            SSL_CTX_free(ctx);
            return NULL;
        }
    
        return ctx;
    }

    3、客户端初始化

    SSL_CTX *ssl_client_init(int verify_type, const char *ca, const char *user_cert, const char *user_key)
    {
    	SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
        if (ctx == NULL) {
            ERR_print_errors_fp(stderr);
            return NULL;
        }
    
        if (verify_type == SSL_VERIFY_NONE)
        {
    		SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,NULL);
        }
        else if (verify_type == SSL_VERIFY_PEER)
        {
        	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
    	    if (SSL_CTX_load_verify_locations(ctx, ca,NULL) <= 0)
    	    {
    	        ERR_print_errors_fp(stderr);
    	        SSL_CTX_free(ctx);
    	        return NULL;
    	    }
    
    	    if (SSL_CTX_use_certificate_file(ctx, user_cert, SSL_FILETYPE_PEM) <= 0) 
    	    {
    	        ERR_print_errors_fp(stderr);
    	        SSL_CTX_free(ctx);
    	        return NULL;
    	    }
    	    
    	    if (SSL_CTX_use_PrivateKey_file(ctx, user_key, SSL_FILETYPE_PEM) <= 0) 
    	    {
    	        ERR_print_errors_fp(stderr);
    	        SSL_CTX_free(ctx);
    	        return NULL;
    	    }
    	    
    	    if (!SSL_CTX_check_private_key(ctx)) 
    	    {
    	        ERR_print_errors_fp(stderr);
    	        SSL_CTX_free(ctx);
    	        return NULL;
    	    }
        }
        else
        {
        	SSL_CTX_free(ctx);
        	return NULL;
        }	
    
        return ctx;
    }

    4、封装ssl握手函数

    /*
    	handshake_type:	1 connect 状态 
    					2 accept 状态
     */
    SSL *sslDoHandshake(int handshake_type, SSL_CTX *ctx, int fd, int *err_code)
    {
        if (ctx == NULL)
    	{
    		return NULL;
    	}
        //基于 ctx 创建一个新的 SSL 句柄
        SSL *ssl = SSL_new(ctx);
    	if (!ssl)
    	{
    		ssl = NULL;
    		return NULL;
    	}
        //将 socket 加入到 SSL
        if (!SSL_set_fd(ssl, fd))
        {
            SSL_free(ssl);
    		ssl = NULL;
    		return NULL;
    	}
    
    	if (handshake_type == 1)
    	{
    		//设置 SSL 为 connect 状态 
    		SSL_set_connect_state(ssl);
    	}
    	else if (handshake_type == 2)
    	{
    		//设置 SSL 为 accept 状态 
        	SSL_set_accept_state(ssl);
    	}
    	else
    	{
    		SSL_free(ssl);
    		ssl = NULL;
    		return NULL;
    	}
    
    	int ret, err, cnt = 0;
    	
    	while ((ret = SSL_do_handshake(ssl)) != 1)
    	{
    		err = SSL_get_error(ssl, ret);
    		if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ)
    		{	
    			usleep(100*1000);
    			cnt++;
    			if (cnt == 10)  //防止 SSL_do_handshake 一直失败,无法跳出循环
    			{
            		SSL_free(ssl);
    				ssl = NULL;
    				break;	
    			}
    			continue;
    		}
    		else
    		{
    			*err_code = err;
    			//err == 5 SSL_ERROR_SYSCALL 关闭相关资源,重新连接
    			
    			printf("SSL_do_handshake failed, err_code : %d\n", err);
    			ERR_print_errors_fp(stderr);
                SSL_shutdown(ssl);
            	SSL_free(ssl);
    			ssl = NULL;
    			break;
    		}
    	}
    	
    	printf("SSL_do_handshake, ret : %d\n", ret);
        return ssl;	
    }

    5、封装SSL_read函数

    /*
     	SSL_read(SSL *ssl,char *buf,int num)
    	正常:返回1到num个字节数
    	错误:返回0或负数
    */
    int sslRead(SSL *ssl, int fd, char *buf, int len, int timeout)
    {
    	if (ssl == NULL)
    	{
    		return -1;
    	}
    	
    	int err, res, ret, bytes = 0, cnt = 0;
        fd_set rfds;  
        struct timeval tv;  
        
        if (timeout > 0)
    	{
    	    FD_ZERO(&rfds);  
        	FD_SET(fd, &rfds); 
    	}
    
    	do
    	{	
            if (timeout > 0)
    		{
    			tv.tv_sec = timeout/1000;  
    	    	tv.tv_usec = timeout%1000;  
    			ret = select(fd + 1, &rfds, NULL, NULL, &tv); 
    			if (ret == 0)
    			{
    				printf("time out\n");
    				return -2;
    			}
    			else if (ret < 0)
    			{
    				return -1;
    			}
    
    			if(!FD_ISSET(fd,&rfds))
    			{
    				return -1;
    			}
    		}	
    	
    		res = SSL_read(ssl, buf + bytes, len);
    		if (res >= 1)
    		{
    			cnt = 0;
    			bytes += res;
                len -= res;
    		}
    		else
    		{
    			err = SSL_get_error(ssl, res);
    			if (err == SSL_ERROR_WANT_READ)
    			{
    				usleep(100*1000);
    				cnt++;
    				if (cnt == 5)
    				{
    					return -2;
    				}	
    				continue;
    			}
    			else
    			{
    				printf("ssl read failed...\n");
                	ERR_print_errors_fp(stderr); 
    
    				if (err == SSL_ERROR_SYSCALL)  //可能是对方已经关闭连接,因此要关闭相关资源,重新连接
    				{
    					return -5;
    				}
    				
                	return -1;
    			}	
    		}	
    	}
    	while(len > 0 && SSL_pending(ssl));   //SSL_pending(ssl)返回可读的ssl数据字节数
    	
    	return bytes;
    }
    注:当返回0时,可能是SSL_pending的问题导致未进入循环,应再次调用sslRead

    6、封装SSL_write函数

    /*
     	SSL_write(SSL *ssl,const char *buf,int num)
    	正常:返回1到num个字节数
    	错误:返回0或负数
    */
    int sslWrite(SSL *ssl, char *buf, int len)
    {
    	if (ssl == NULL)
    	{
    		return -1;
    	}
    	
    	int err, res, bytes = 0, cnt = 0;
    
    	while(len > 0)
    	{
            res = SSL_write(ssl, buf + bytes, len);	
            if (res >= 1)
    		{
    			cnt = 0;
    			bytes += res;
                len -= res;
    		}
    		else
    		{
    			err = SSL_get_error(ssl, res);
    			if (err == SSL_ERROR_WANT_WRITE)
    			{
    				usleep(100*1000);
    				cnt++;
    				if (cnt == 5)
    				{
    					return -2;
    				}	
    				continue;
    			}
    			else
    			{
    				printf("ssl write failed...\n");
                	ERR_print_errors_fp(stderr); 
    
    				if (err == SSL_ERROR_SYSCALL) //可能是对方已经关闭连接,因此要关闭相关资源,重新连接
    				{
    					return -5;
    				}
    
                	return -1;
    			}	
    		}
    	}
    
    	printf("ssl write, bytes:%d\n", bytes);
    	return bytes;
    }

    7、demo示例

    int main(int argc, char const *argv[])
    {
    	//客户端demo流程
    	/*
    	ssl_service_init
    	ssl_client_init
    	创建socket
    	sslDoHandshake
    	sslRead或sslWrite
    	*/
    
    	//服务端demo流程
    	/*
    	ssl_service_init
    	ssl_server_init
    	创建socket
    	sslDoHandshake
    	sslRead或sslWrite
    	*/
    	return 0;
    }

    8、总结与说明

    8.1、openssl官方函数:https://www.ibm.com/docs/en/ztpf/2021?topic=services-ztpf-cc-apis
    8.2、如果移植到设备上运行时出现未知错误,可能是编译openssl时存在问题
    8.3、如果出现 SSL_ERROR_SYSCALL,没有重新初始化ssl,将会出现以下问题,导致CPU异常偏高
    [ 1954.054545] [drm:rot_client_get_device] *ERROR* wait2start timeout. timeout=5jif, ret=0
    [ 1954.074862] [drm:rot_client_exec_fb_sync] *ERROR* wait4finish timeout: 5jif --> 0

    ——————————————

    仅供学习与参考

    展开全文
  • openssl编程实例

    2017-09-04 08:55:44
    openssl编程实例,仅供个人学习openssl,版权他人所有,如有侵权请告知
  • OpenSSL编程手册

    2019-05-25 02:08:51
    openssl_program.rar,openssl_program.chm
  • Openssl编程

    2016-11-08 17:55:59
    Openssl编程
  • OPENSSL编程

    2013-09-30 09:35:42
    江南计算技术研究所 赵春平 著 学习 OpenSSL 的朋友,这里有一分很不错的文档。拿出来共享,希望对对学习有所帮助。
  • openssl编程.doc

    2019-03-21 01:53:26
    openssl编程.rar,openssl编程.doc
  • 可用的windows下编译过的OpenSSL编程环境,VS编程环境中增加include、lib路径使用
  • 第一次跑起openssl示例并不太简单,本文的目的是为了让这个过程变得非常简单。在开始之前,要非常感谢周立发同学,正是通过他共享的示例,较轻松的入了门。 本文档对他共享的示例中的一个小错误进行了修正,并提供了...
  • 这周上实验室课,关于openssl编程,自己试着用C语言做了个聊天室,挺无聊的,可以多人聊天,服务器总共用了三个线程,主线程负责UI,一个线程监听,另一个与所有客户端收发数据。客户端两个线程,UI和收发数据就行...
  • openssl编程 书签版

    2016-01-20 15:00:43
    openssl编程 书签版 openssl 入门 必备良品
  • openssl编程1

    2022-08-03 21:52:13
    摘要算法101.3公钥算法111.4回调函数13第二章2.12.22.2.12.2.22.32.4第三章堆栈193.13.2数据结构193.3源码193.4定义
  • Openssl编程1

    2022-08-03 20:38:34
    摘要算法91.3公钥算法 91.4回调函数 11第二章2.12.22.2.12.2.22.32.4第三章堆栈 173.13.2数据结构 173.3源码 183.
  • Openssl编程pdf.zip

    2021-11-26 18:22:37
    Openssl编程pdf
  • OpenSSL编程入门教程

    千次阅读 2017-12-19 10:35:55
    SSL编程入门教程 OpenSSL是一个开放源代码的SSL协议的产品实现,它采用C语言作为开发语言,具备了跨系统的性能。调用OpenSSL的函数就可以实现一个SSL加密的安全数据传输通道,从而保护客户端和服务器之间数据的...

    OpenSSL编程入门教程


    OpenSSL是一个开放源代码的SSL协议的产品实现,它采用C语言作为开发语言,具备了跨系统的性能。调用OpenSSL的函数就可以实现一个SSL加密的安全数据传输通道,从而保护客户端和服务器之间数据的安全。


    头文件:
    #include <openssl/ssl.h>
    #include <openssl/err.h>

    基于OpenSSL的程序都要遵循以下几个步骤:

    (1 ) OpenSSL初始化

    在使用OpenSSL之前,必须进行相应的协议初始化工作,这可以通过下面的函数实现:

    int SSL_library_int(void);

    (2 ) 选择会话协议

    在利用OpenSSL开始SSL会话之前,需要为客户端和服务器制定本次会话采用的协议,目前能够使用的协议包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。

    需要注意的是,客户端和服务器必须使用相互兼容的协议,否则SSL会话将无法正常进行。

    (3 ) 创建会话环境

    在OpenSSL中创建的SSL会话环境称为CTX,使用不同的协议会话,其环境也不一样的。

    申请SSL会话环境的OpenSSL函数是:

    SSL_CTX *SSL_CTX_new(SSL_METHOD * method);

    当SSL会话环境申请成功后,还要根据实际的需要设置CTX的属性,通常的设置是指定SSL握手阶段证书的验证方式和加载自己的证书。

    制定证书验证方式的函数是:

    int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));

    为SSL会话环境加载CA证书的函数是:

    SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);

    为SSL会话加载用户证书的函数是:

    SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);

    为SSL会话加载用户私钥的函数是:

    SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);

    在将证书和私钥加载到SSL会话环境之后,就可以调用下面的函数来验证私钥和证书是否相符

    int SSL_CTX_check_private_key(SSL_CTX *ctx);

    (4) 建立SSL套接字

    SSL套接字是建立在普通的TCP套接字基础之上,在建立SSL套接字时可以使用下面的一些函数:

    SSL *SSl_new(SSL_CTX *ctx);

    //申请一个SSL套接字

    int SSL_set_fd(SSL *ssl,int fd);)

    //绑定读写套接字

    int SSL_set_rfd(SSL *ssl,int fd);

    //绑定只读套接字

    int SSL_set_wfd(SSL *ssl,int fd);

    //绑定只写套接字

    (5) 完成SSL握手

    在成功创建SSL套接字后,客户端应使用函数SSL_connect( )替代传统的函数connect( )来完成握手过程:

    int SSL_connect(SSL *ssl);

    而对服务器来讲,则应使用函数SSL_ accept ( )替代传统的函数accept ( )来完成握手过程:

    int SSL_accept(SSL *ssl);

    握手过程完成之后,通常需要询问通信双方的证书信息,以便进行相应的验证,这可以借助于下面的函数来实现:

    X509 *SSL_get_peer_certificate(SSL *ssl);

    该函数可以从SSL套接字中提取对方的证书信息,这些信息已经被SSL验证过了。

    X509_NAME *X509_get_subject_name(X509 *a);

    该函数得到证书所用者的名字。

    (6) 进行数据传输

    当SSL握手完成之后,就可以进行安全的数据传输了,在数据传输阶段,需要使用SSL_read( )和SSL_write( )来替代传统的read( )和write( )函数,来完成对套接字的读写操作:

    int SSL_read(SSL *ssl,void *buf,int num);

    int SSL_write(SSL *ssl,const void *buf,int num);

    (7 ) 结束SSL通信

    当客户端和服务器之间的数据通信完成之后,调用下面的函数来释放已经申请的SSL资源:

    int SSL_shutdown(SSL *ssl);

    //关闭SSL套接字

    void SSl_free(SSL *ssl);

     //释放SSL套接字

    void SSL_CTX_free(SSL_CTX *ctx); 

    //释放SSL会话环境


    Openssl应用编程框架:

    1.客户端程序的框架为:

    1. meth = SSLv23_client_method();  
    2. ctx = SSL_CTX_new (meth);  
    3. ssl = SSL_new(ctx);  
    4. fd = socket();  
    5. connect();  
    6. SSL_set_fd(ssl,fd);  
    7. SSL_connect(ssl);  
    8. SSL_write(ssl,"Hello world",strlen("Hello World!"));  
    meth = SSLv23_client_method();
    ctx = SSL_CTX_new (meth);
    ssl = SSL_new(ctx);
    fd = socket();
    connect();
    SSL_set_fd(ssl,fd);
    SSL_connect(ssl);
    SSL_write(ssl,"Hello world",strlen("Hello World!"));

    2.服务端程序的框架为:

    1. meth = SSLv23_server_method();  
    2. ctx = SSL_CTX_new (meth);  
    3. ssl = SSL_new(ctx);  
    4. fd = socket();  
    5. bind();  
    6. listen();  
    7. accept();  
    8. SSL_set_fd(ssl,fd);  
    9. SSL_connect(ssl);  
    10. SSL_read (ssl, buf, sizeof(buf));  
    meth = SSLv23_server_method();
    ctx = SSL_CTX_new (meth);
    ssl = SSL_new(ctx);
    fd = socket();
    bind();
    listen();
    accept();
    SSL_set_fd(ssl,fd);
    SSL_connect(ssl);
    SSL_read (ssl, buf, sizeof(buf));

    对程序来说,openssl将整个握手过程用一对函数体现,即客户端的SSL_connect和服务端的SSL_accept.而后的应用层数据交换则用SSL_read和 SSL_write来完成

    Linux下基于OpenSSL的SSL安全通信设计

    本程序可以自由使用,请遵守GPL规范。
    OpenSSL中的SSL安全通信可以分为两类,两类基本上的操作相同,一类是建立SSL环境后使用BIO读写,另一类是直接在socket上建立SSL上下文环境。本文主要讨论在socket上建立SSL环境,以实现安全通信。首先需要生成一对客户机和服务器证书,这可以使用openssl的命令实现。使用赵春平前辈的OpenSSL编程一书中建立SSL测试环境的命令,可以建立一个模拟的CA,生成数字证书。如下:
    1、建立自己的CA
    在OpenSSL的安装目录下的misc目录下,运行脚本sudo ./CA.sh -newCA。运行完后会生成一个demoCA的目录,里面存放了CA的证书和私钥。
    2、生成客户端和服务器证书申请
    openssl req -newkey rsa:1204 -out req1.pem -keyout sslclientkey.pem
    openssl req -newkey rsa:1204 -out req2.pem -keyout sslserverkey.pem
    3、签发客户端和服务器证书
    openssl ca -in req1.pem -out sslclientcert.pem
    openssl ca -in req2.pem -out sslservercert.pem

    然后就可以使用OpenSSL的开源库实现SSL安全通信,本文设计了两种模式的通信,一种是没有建立SSL环境的TCP,另一种是建立了SSL环境的TCP,之后可以使用Linux下的嗅探软件wireshark嗅探出两种模式下的数据包,比较不同。程序设计参考了周立发老师的程序。



    下面首先是服务器端的程序:

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <signal.h>  
    4. #include <errno.h>  
    5. #include <string.h>  
    6. #include <netdb.h>  
    7. #include <resolv.h>  
    8. #include <fcntl.h>  
    9. #include <unistd.h>  
    10. #include <sys/types.h>  
    11. #include <netinet/in.h>  
    12. #include <sys/socket.h>  
    13. #include <sys/wait.h>  
    14. #include <arpa/inet.h>  
    15.   
    16. #include <openssl/bio.h>  
    17. #include <openssl/err.h>  
    18. #include <openssl/ssl.h>  
    19. #include "tcp_video.h"  
    20.   
    21. #define MAXSIZE 1024 //每次最大数据传输量  
    22.   
    23. #define PKEY_FILE "sslserverkey.pem"  
    24. #define CERT_FILE "sslservercert.pem"  
    25.   
    26. int main()  
    27. {  
    28.     int sockfd,client_fd;  
    29.     socklen_t len;  
    30.    
    31.     SSL_CTX *ctx;  
    32.     
    33.     char serverbuf[MAXSIZE];  
    34.   
    35.     ERR_load_BIO_strings();  
    36.     SSL_library_init();  
    37.     OpenSSL_add_all_algorithms();  
    38.     SSL_load_error_strings();  
    39.     ctx = SSL_CTX_new(SSLv23_server_method());  
    40.     if (ctx == NULL)  
    41.     {  
    42.         ERR_print_errors_fp(stdout);  
    43.         exit(1);  
    44.     }  
    45.     if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))  
    46.     {  
    47.         ERR_print_errors_fp(stdout);  
    48.         exit(1);  
    49.     }  
    50.     if (!SSL_CTX_use_PrivateKey_file(ctx, PKEY_FILE, SSL_FILETYPE_PEM) )  
    51.     {  
    52.         ERR_print_errors_fp(stdout);  
    53.         exit(1);  
    54.     }  
    55.     if (!SSL_CTX_check_private_key(ctx))  
    56.     {  
    57.         ERR_print_errors_fp(stdout);  
    58.         exit(1);  
    59.     }  
    60.     int chose=0;  
    61.     signal(SIGPIPE,SIG_IGN);  
    62.     tcpserver_init(&sockfd);  
    63.     while(1)  
    64.     {  
    65.         printf("Please Chose Channel No.:\n");  
    66.         printf("1.:SSL Protocol Channel\n");  
    67.         printf("2.:TCP Protocol Channel\n");  
    68.         scanf("%d",&chose);  
    69.         if(chose==1)  
    70.         {  
    71.             SSL *ssl;  
    72.             tcp_accept(sockfd,&client_fd);  
    73.             ssl = SSL_new(ctx);  
    74.             SSL_set_fd(ssl, client_fd);  
    75.             if (SSL_accept(ssl) == -1)  
    76.             {  
    77.                 perror("accept");  
    78.                 close(client_fd);  
    79.                 break;  
    80.             }  
    81.             // 接收消息  
    82.             bzero(serverbuf, MAXSIZE);  
    83.              
    84.             len = SSL_read(ssl,serverbuf, MAXSIZE);  
    85.             if (len > 0)  
    86.                 printf("接收消息成功:'%s',共%d个字节的数据\n",serverbuf, len);  
    87.             else  
    88.                 printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));  
    89.              
    90.             SSL_shutdown(ssl);  
    91.             SSL_free(ssl);  
    92.             close(client_fd);  
    93.         }  
    94.         else if(chose==2)  
    95.         {  
    96.             tcp_accept(sockfd,&client_fd);  
    97.             len=recv(client_fd,serverbuf, MAXSIZE,0);  
    98.             if (len > 0)  
    99.                 printf("接收消息成功:'%s',共%d个字节的数据\n",serverbuf, len);  
    100.             else  
    101.                 printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));  
    102.             close(client_fd);  
    103.         }  
    104.         chose=0;  
    105.     }  
    106.     close(sockfd);  
    107.     SSL_CTX_free(ctx);  
    108.     return 0;  
    109.   
    110. }//main  
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <resolv.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <arpa/inet.h>
    
    #include <openssl/bio.h>
    #include <openssl/err.h>
    #include <openssl/ssl.h>
    #include "tcp_video.h"
    
    #define MAXSIZE 1024 //每次最大数据传输量
    
    #define PKEY_FILE "sslserverkey.pem"
    #define CERT_FILE "sslservercert.pem"
    
    int main()
    {
        int sockfd,client_fd;
        socklen_t len;
     
        SSL_CTX *ctx;
      
        char serverbuf[MAXSIZE];
    
        ERR_load_BIO_strings();
        SSL_library_init();
        OpenSSL_add_all_algorithms();
        SSL_load_error_strings();
        ctx = SSL_CTX_new(SSLv23_server_method());
        if (ctx == NULL)
        {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
        {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        if (!SSL_CTX_use_PrivateKey_file(ctx, PKEY_FILE, SSL_FILETYPE_PEM) )
        {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        if (!SSL_CTX_check_private_key(ctx))
        {
            ERR_print_errors_fp(stdout);
            exit(1);
        }
        int chose=0;
        signal(SIGPIPE,SIG_IGN);
        tcpserver_init(&sockfd);
        while(1)
        {
            printf("Please Chose Channel No.:\n");
            printf("1.:SSL Protocol Channel\n");
            printf("2.:TCP Protocol Channel\n");
            scanf("%d",&chose);
            if(chose==1)
            {
                SSL *ssl;
                tcp_accept(sockfd,&client_fd);
                ssl = SSL_new(ctx);
                SSL_set_fd(ssl, client_fd);
                if (SSL_accept(ssl) == -1)
                {
                    perror("accept");
                    close(client_fd);
                    break;
                }
                // 接收消息
                bzero(serverbuf, MAXSIZE);
               
                len = SSL_read(ssl,serverbuf, MAXSIZE);
                if (len > 0)
                    printf("接收消息成功:'%s',共%d个字节的数据\n",serverbuf, len);
                else
                    printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));
               
                SSL_shutdown(ssl);
                SSL_free(ssl);
                close(client_fd);
            }
            else if(chose==2)
            {
                tcp_accept(sockfd,&client_fd);
                len=recv(client_fd,serverbuf, MAXSIZE,0);
                if (len > 0)
                    printf("接收消息成功:'%s',共%d个字节的数据\n",serverbuf, len);
                else
                    printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));
                close(client_fd);
            }
            chose=0;
        }
        close(sockfd);
        SSL_CTX_free(ctx);
        return 0;
    
    }//main

    再次是客户端的程序

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <errno.h>  
    4. #include <string.h>  
    5. #include <netdb.h>  
    6. #include <resolv.h>  
    7. #include <fcntl.h>  
    8. #include <unistd.h>  
    9. #include <sys/types.h>  
    10. #include <netinet/in.h>  
    11. #include <sys/socket.h>  
    12. #include <sys/wait.h>  
    13. #include <arpa/inet.h>  
    14.   
    15. #include <openssl/bio.h>  
    16. #include <openssl/err.h>  
    17. #include <openssl/ssl.h>  
    18. #include "tcp_video.h"  
    19.   
    20. #define MAXSIZE 1024 //每次最大数据传输量  
    21.   
    22. void ShowCerts(SSL * ssl)  
    23. {  
    24.     X509 *cert;  
    25.     char *line;  
    26.   
    27.     cert = SSL_get_peer_certificate(ssl);  
    28.     if (cert != NULL)  
    29.     {  
    30.         printf("数字证书信息:\n");  
    31.         line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);  
    32.         printf("证书: %s\n", line);  
    33.         free(line);  
    34.         line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);  
    35.         printf("颁发者: %s\n", line);  
    36.         free(line);  
    37.         X509_free(cert);  
    38.     }  
    39.     else  
    40.         printf("无证书信息!\n");  
    41. }  
    42. int main()  
    43. {  
    44.     char *hostname="127.0.0.1";  
    45.     int sockfd, len;  
    46.     char clientbuf[MAXSIZE];  
    47.     struct hostent *host;//gethostbyname函数的参数返回  
    48.     struct sockaddr_in serv_addr;  
    49.     SSL_CTX *ctx;  
    50.     SSL *ssl;  
    51.      
    52.     SSL_library_init();  
    53.     OpenSSL_add_all_algorithms();  
    54.     SSL_load_error_strings();  
    55.     ctx = SSL_CTX_new(SSLv23_client_method());  
    56.     if (ctx == NULL)  
    57.     {  
    58.         ERR_print_errors_fp(stdout);  
    59.         exit(1);  
    60.     }  
    61.     int chose=0;  
    62.     printf("Please Chose Channel No.:\n");  
    63.     printf("1.:SSL Protocol Channel\n");  
    64.     printf("2.:TCP Protocol Channel\n");  
    65.     scanf("%d",&chose);  
    66.     serv_addr=tcpclient_init(&sockfd);  
    67.     if(chose==1)  
    68.     {  
    69.         tcp_connect(&sockfd,serv_addr);  
    70.          
    71.         ssl = SSL_new(ctx);  
    72.         SSL_set_fd(ssl, sockfd);  
    73.          
    74.         if (SSL_connect(ssl) == -1)  
    75.             ERR_print_errors_fp(stderr);  
    76.         else  
    77.         {  
    78.             printf("Connected with %s encryption\n", SSL_get_cipher(ssl));  
    79.             ShowCerts(ssl);  
    80.         }  
    81.     
    82.         bzero(clientbuf, MAXSIZE);  
    83.         strcpy(clientbuf, "id:am3517&pw:am3517\n");  
    84.         len = SSL_write(ssl, clientbuf, strlen(clientbuf));  
    85.         if (len < 0)  
    86.             printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",clientbuf, errno, strerror(errno));  
    87.         else  
    88.             printf("消息'%s'发送成功,共发送了%d个字节!\n",clientbuf, len);  
    89.   
    90.         SSL_shutdown(ssl);  
    91.         SSL_free(ssl);  
    92.     }  
    93.     else if(chose==2)  
    94.     {  
    95.         tcp_connect(&sockfd,serv_addr);  
    96.          
    97.         bzero(clientbuf, MAXSIZE);  
    98.         strcpy(clientbuf, "id:am3517&pw:am3517\n");  
    99.         len = send(sockfd, clientbuf, strlen(clientbuf),0);  
    100.         if (len < 0)  
    101.             printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",clientbuf, errno, strerror(errno));  
    102.         else  
    103.             printf("消息'%s'发送成功,共发送了%d个字节!\n",clientbuf, len);  
    104.     }  
    105.     close(sockfd);  
    106.     SSL_CTX_free(ctx);  
    107.     return 0;  
    108. }  
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <resolv.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <arpa/inet.h>
    
    #include <openssl/bio.h>
    #include <openssl/err.h>
    #include <openssl/ssl.h>
    #include "tcp_video.h"
    
    #define MAXSIZE 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()
    {
        char *hostname="127.0.0.1";
        int sockfd, len;
        char clientbuf[MAXSIZE];
        struct hostent *host;//gethostbyname函数的参数返回
        struct sockaddr_in serv_addr;
        SSL_CTX *ctx;
        SSL *ssl;
       
        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);
        }
        int chose=0;
        printf("Please Chose Channel No.:\n");
        printf("1.:SSL Protocol Channel\n");
        printf("2.:TCP Protocol Channel\n");
        scanf("%d",&chose);
        serv_addr=tcpclient_init(&sockfd);
        if(chose==1)
        {
            tcp_connect(&sockfd,serv_addr);
           
            ssl = SSL_new(ctx);
            SSL_set_fd(ssl, sockfd);
           
            if (SSL_connect(ssl) == -1)
                ERR_print_errors_fp(stderr);
            else
            {
                printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
                ShowCerts(ssl);
            }
      
            bzero(clientbuf, MAXSIZE);
            strcpy(clientbuf, "id:am3517&pw:am3517\n");
            len = SSL_write(ssl, clientbuf, strlen(clientbuf));
            if (len < 0)
                printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",clientbuf, errno, strerror(errno));
            else
                printf("消息'%s'发送成功,共发送了%d个字节!\n",clientbuf, len);
    
            SSL_shutdown(ssl);
            SSL_free(ssl);
        }
        else if(chose==2)
        {
            tcp_connect(&sockfd,serv_addr);
           
            bzero(clientbuf, MAXSIZE);
            strcpy(clientbuf, "id:am3517&pw:am3517\n");
            len = send(sockfd, clientbuf, strlen(clientbuf),0);
            if (len < 0)
                printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",clientbuf, errno, strerror(errno));
            else
                printf("消息'%s'发送成功,共发送了%d个字节!\n",clientbuf, len);
        }
        close(sockfd);
        SSL_CTX_free(ctx);
        return 0;
    }

    编译是需要OpenSSL库的支持,怎么安装OpenSSL在这里就不说了,网上有很多例子,另外在Ubuntu系统下可以直接使用新力得软件包安装。编辑时需要加 -lssl 选项,另外如果要调试,需要加 -g选项。
    另外,程序中使用的tcp连接的函数,可以使用下面的函数,本系统使用端口7838。

    1. void tcpserver_init(int *sockfd)  
    2. {  
    3.     socklen_t len;  
    4.     struct sockaddr_in my_addr;  
    5.     unsigned int myport, lisnum;  
    6.   
    7.     myport = 7838;  
    8.     lisnum = 1;  
    9.   
    10.     if ((*sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)  
    11.     {  
    12.         perror("socket");  
    13.         exit(1);  
    14.     }  
    15.     else  
    16.         printf("socket created\n");  
    17.   
    18.     bzero(&my_addr, sizeof(my_addr));  
    19.     my_addr.sin_family = PF_INET;  
    20.     my_addr.sin_port = htons(myport);  
    21.     my_addr.sin_addr.s_addr = INADDR_ANY;  
    22.   
    23.     if(bind(*sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)  
    24.     {  
    25.         perror("bind");  
    26.         exit(1);  
    27.     }  
    28.     else  
    29.         printf("binded\n");  
    30.   
    31.     if (listen(*sockfd, lisnum) == -1)  
    32.     {  
    33.         perror("listen");  
    34.         exit(1);  
    35.     }  
    36.     else  
    37.         printf("begin listen\n");  
    38. }  
    39. void tcp_accept(int sockfd,int *new_fd)  
    40. {  
    41.     struct sockaddr_in their_addr;  
    42.     socklen_t len;  
    43.     len = sizeof(struct sockaddr);  
    44.     if ((*new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &len)) == -1)  
    45.     {  
    46.         perror("accept");  
    47.         exit(errno);  
    48.     }  
    49.     else  
    50.         printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), *new_fd);  
    51.     int flags;  
    52.     flags = fcntl (sockfd, F_GETFL);   
    53.     if (flags & O_NONBLOCK)  
    54.     {  
    55.         //fcntl (sockfd, F_SETFL, flags-O_NONBLOCK);  
    56.         fcntl(sockfd,F_SETFL,flags&(~O_NONBLOCK));  
    57.     }  
    58. }  
    59. struct sockaddr_in tcpclient_init(int *sockfd)  
    60. {  
    61.     int len;  
    62.     struct sockaddr_in dest;  
    63.   
    64.     char parainfo[3][20];  
    65.     printf("input server IP:\n");  
    66.     scanf("%s",parainfo[0]);  
    67.     printf("input server port:\n");  
    68.     scanf("%s",parainfo[1]);  
    69.     if((*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
    70.     {  
    71.         perror("Socket");  
    72.         exit(errno);  
    73.     }  
    74.     printf("socket created\n");  
    75.   
    76.     bzero(&dest, sizeof(dest));  
    77.     dest.sin_family = AF_INET;  
    78.     dest.sin_port = htons(atoi(parainfo[1]));  
    79.     if (inet_aton(parainfo[0], (struct in_addr *) &dest.sin_addr.s_addr) == 0)  
    80.     {  
    81.         perror(parainfo[0]);  
    82.         exit(errno);  
    83.     }  
    84.     printf("address created\n");  
    85.     return dest;  
    86. }  
    87. void tcp_connect(int *sockfd,struct sockaddr_in dest)  
    88. {  
    89.     if (connect(*sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0)  
    90.     {  
    91.         perror("Connect ");  
    92.         exit(errno);  
    93.     }  
    94.     printf("server connected\n");  
    95.     int flags;  
    96.     flags = fcntl (sockfd, F_GETFL);   
    97.     if (flags & O_NONBLOCK)  
    98.     {  
    99.         //fcntl (sockfd, F_SETFL, flags-O_NONBLOCK);  
    100.         fcntl(sockfd,F_SETFL,flags&(~O_NONBLOCK));  
    101.     }  
    102. }  
    void tcpserver_init(int *sockfd)
    {
        socklen_t len;
        struct sockaddr_in my_addr;
        unsigned int myport, lisnum;
    
        myport = 7838;
        lisnum = 1;
    
        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");
    }
    void tcp_accept(int sockfd,int *new_fd)
    {
        struct sockaddr_in their_addr;
        socklen_t len;
        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);
        int flags;
        flags = fcntl (sockfd, F_GETFL); 
        if (flags & O_NONBLOCK)
        {
            //fcntl (sockfd, F_SETFL, flags-O_NONBLOCK);
            fcntl(sockfd,F_SETFL,flags&(~O_NONBLOCK));
        }
    }
    struct sockaddr_in tcpclient_init(int *sockfd)
    {
        int len;
        struct sockaddr_in dest;
    
        char parainfo[3][20];
        printf("input server IP:\n");
        scanf("%s",parainfo[0]);
        printf("input server port:\n");
        scanf("%s",parainfo[1]);
        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(parainfo[1]));
        if (inet_aton(parainfo[0], (struct in_addr *) &dest.sin_addr.s_addr) == 0)
        {
            perror(parainfo[0]);
            exit(errno);
        }
        printf("address created\n");
        return dest;
    }
    void tcp_connect(int *sockfd,struct sockaddr_in dest)
    {
        if (connect(*sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0)
        {
            perror("Connect ");
            exit(errno);
        }
        printf("server connected\n");
        int flags;
        flags = fcntl (sockfd, F_GETFL); 
        if (flags & O_NONBLOCK)
        {
            //fcntl (sockfd, F_SETFL, flags-O_NONBLOCK);
            fcntl(sockfd,F_SETFL,flags&(~O_NONBLOCK));
        }
    }


    ###########################################################################

    服务器端源代码如下:

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <errno.h>  
    4. #include <string.h>  
    5. #include <sys/types.h>  
    6. #include <netinet/in.h>  
    7. #include <sys/socket.h>  
    8. #include <sys/wait.h>  
    9. #include <unistd.h>  
    10. #include <arpa/inet.h>  
    11. #include <openssl/ssl.h>  
    12. #include <openssl/err.h>  
    13.   
    14. #define MAXBUF 1024  
    15.   
    16. int main(int argc, char **argv)  
    17. {  
    18. int sockfd, new_fd;  
    19. socklen_t len;  
    20. struct sockaddr_in my_addr, their_addr;  
    21. unsigned int myport, lisnum;  
    22. char buf[MAXBUF + 1];  
    23. SSL_CTX *ctx;  
    24.   
    25. if (argv[1])  
    26. myport = atoi(argv[1]);  
    27. else  
    28. myport = 7838;  
    29. if (argv[2])  
    30. lisnum = atoi(argv[2]);  
    31. else  
    32. lisnum = 2;  
    33.   
    34. SSL_library_init();  
    35. OpenSSL_add_all_algorithms();  
    36. SSL_load_error_strings();  
    37. ctx = SSL_CTX_new(SSLv23_server_method());  
    38. if (ctx == NULL) {  
    39. ERR_print_errors_fp(stdout);  
    40. exit(1);  
    41. }  
    42. if (SSL_CTX_use_certificate_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {  
    43. ERR_print_errors_fp(stdout);  
    44. exit(1);  
    45. }  
    46. if (SSL_CTX_use_PrivateKey_file(ctx, argv[5], SSL_FILETYPE_PEM) <= 0) {  
    47. ERR_print_errors_fp(stdout);  
    48. exit(1);  
    49. }  
    50. if (!SSL_CTX_check_private_key(ctx)) {  
    51. ERR_print_errors_fp(stdout);  
    52. exit(1);  
    53. }  
    54. if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {  
    55. perror("socket");  
    56. exit(1);  
    57. else  
    58. printf("socket created\n");  
    59.   
    60. bzero(&my_addr, sizeof(my_addr));  
    61. my_addr.sin_family = PF_INET;  
    62. my_addr.sin_port = htons(myport);  
    63. if (argv[3])  
    64. my_addr.sin_addr.s_addr = inet_addr(argv[3]);  
    65. else  
    66. my_addr.sin_addr.s_addr = INADDR_ANY;  
    67.   
    68. if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) {  
    69. perror("bind");  
    70. exit(1);  
    71. else  
    72. printf("binded\n");  
    73.   
    74. if (listen(sockfd, lisnum) == -1) {  
    75. perror("listen");  
    76. exit(1);  
    77. else  
    78. printf("begin listen\n");  
    79.   
    80. while (1) {  
    81. SSL *ssl;  
    82. len = sizeof(struct sockaddr);  
    83.   
    84. if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len)) == -1) {  
    85. perror("accept");  
    86. exit(errno);  
    87. else  
    88. printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);  
    89.   
    90. ssl = SSL_new(ctx);  
    91. SSL_set_fd(ssl, new_fd);  
    92. if (SSL_accept(ssl) == -1) {  
    93. perror("accept");  
    94. close(new_fd);  
    95. break;  
    96. }  
    97.   
    98. bzero(buf, MAXBUF + 1);  
    99. strcpy(buf, "server->client");  
    100. len = SSL_write(ssl, buf, strlen(buf));  
    101.   
    102. if (len <= 0) {  
    103. printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buf, errno, strerror(errno));  
    104. goto finish;  
    105. else  
    106. printf("消息'%s'发送成功,共发送了%d个字节!\n",buf, len);  
    107.   
    108. bzero(buf, MAXBUF + 1);  
    109. len = SSL_read(ssl, buf, MAXBUF);  
    110. if (len > 0)  
    111. printf("接收消息成功:'%s',共%d个字节的数据\n",buf, len);  
    112. else  
    113. printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));  
    114.   
    115. finish:  
    116. SSL_shutdown(ssl);  
    117. SSL_free(ssl);  
    118. close(new_fd);  
    119. }  
    120. close(sockfd);  
    121. SSL_CTX_free(ctx);  
    122. return 0;  
    123. }  
    #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_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(SSLv23_server_method());
    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);
    }
    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);
    
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, new_fd);
    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_shutdown(ssl);
    SSL_free(ssl);
    close(new_fd);
    }
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
    }

    客户端源代码如下:

    1. #include <stdio.h>  
    2. #include <string.h>  
    3. #include <errno.h>  
    4. #include <sys/socket.h>  
    5. #include <resolv.h>  
    6. #include <stdlib.h>  
    7. #include <netinet/in.h>  
    8. #include <arpa/inet.h>  
    9. #include <unistd.h>  
    10. #include <openssl/ssl.h>  
    11. #include <openssl/err.h>  
    12.   
    13. #define MAXBUF 1024  
    14.   
    15. void ShowCerts(SSL * ssl)  
    16. {  
    17. X509 *cert;  
    18. char *line;  
    19.   
    20. cert = SSL_get_peer_certificate(ssl);  
    21. if (cert != NULL) {  
    22. printf("数字证书信息:\n");  
    23. line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);  
    24. printf("证书: %s\n", line);  
    25. free(line);  
    26. line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);  
    27. printf("颁发者: %s\n", line);  
    28. free(line);  
    29. X509_free(cert);  
    30. else  
    31. printf("无证书信息!\n");  
    32. }  
    33.   
    34. int main(int argc, char **argv)  
    35. {  
    36. int sockfd, len;  
    37. struct sockaddr_in dest;  
    38. char buffer[MAXBUF + 1];  
    39. SSL_CTX *ctx;  
    40. SSL *ssl;  
    41.   
    42. if (argc != 3) {  
    43. printf  
    44. ("参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",argv[0], argv[0]);  
    45. exit(0);  
    46. }  
    47.   
    48. SSL_library_init();  
    49. OpenSSL_add_all_algorithms();  
    50. SSL_load_error_strings();  
    51. ctx = SSL_CTX_new(SSLv23_client_method());  
    52. if (ctx == NULL) {  
    53. ERR_print_errors_fp(stdout);  
    54. exit(1);  
    55. }  
    56.   
    57. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {  
    58. perror("Socket");  
    59. exit(errno);  
    60. }  
    61. printf("socket created\n");  
    62.   
    63. bzero(&dest, sizeof(dest));  
    64. dest.sin_family = AF_INET;  
    65. dest.sin_port = htons(atoi(argv[2]));  
    66. if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {  
    67. perror(argv[1]);  
    68. exit(errno);  
    69. }  
    70. printf("address created\n");  
    71. if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {  
    72. perror("Connect ");  
    73. exit(errno);  
    74. }  
    75. printf("server connected\n");  
    76.   
    77. ssl = SSL_new(ctx);  
    78. SSL_set_fd(ssl, sockfd);  
    79.   
    80. if (SSL_connect(ssl) == -1)  
    81. ERR_print_errors_fp(stderr);  
    82. else {  
    83. printf("Connected with %s encryption\n", SSL_get_cipher(ssl));  
    84. ShowCerts(ssl);  
    85. }  
    86.   
    87. bzero(buffer, MAXBUF + 1);  
    88. len = SSL_read(ssl, buffer, MAXBUF);  
    89. if (len > 0)  
    90. printf("接收消息成功:'%s',共%d个字节的数据\n",buffer, len);  
    91. else {  
    92. printf  
    93. ("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));  
    94. goto finish;  
    95. }  
    96. bzero(buffer, MAXBUF + 1);  
    97. strcpy(buffer, "from client->server");  
    98.   
    99. len = SSL_write(ssl, buffer, strlen(buffer));  
    100. if (len < 0)  
    101. printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buffer, errno, strerror(errno));  
    102. else  
    103. printf("消息'%s'发送成功,共发送了%d个字节!\n",buffer, len);  
    104.   
    105. finish:  
    106. SSL_shutdown(ssl);  
    107. SSL_free(ssl);  
    108. close(sockfd);  
    109. SSL_CTX_free(ctx);  
    110. return 0;  
    111. }  
    #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_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);
    }
    
    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");
    
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sockfd);
    
    if (SSL_connect(ssl) == -1)
    ERR_print_errors_fp(stderr);
    else {
    printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
    ShowCerts(ssl);
    }
    
    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;
    }

    编译程序用下列命令:
    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

    具体请参考 “OpenSSL体系下使用密钥数字证书等”

    如果想对SSL有更深入的了解,请学习计算机安全相关的内容,尤其是非对称加密技术。
    如果想对SSL库的源代码有深入学习,请去 www.openssl.org下载源码来阅读。


    展开全文
  • Openssl编程.rar

    2020-11-24 10:18:13
    openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编...
  • openssl编程-基础知识-OpenSSL简介

    参考链接

    OpenSSL

    简介

    • 它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能

    安装

    • 运行./config --prefix=/usr/local/openssl  即生成动态库,且将其安装在 /usr/local/openssl  文件夹下
    • 更多选项用./config --help 来查看
    • 比如:no-mdc2、no-cast no-rc2、no-rc5、no-ripemd、no-rc4 no-des 、no-md2、no-md4、no-idea 、 no-aes、no-bf、no-err、no-dsa、no-dh、no-ec、no-hw、no-asm、no-krb5、no-dso 、no-threads 、 no-zlib、-DOPENSSL_NO_HASH_COMP、-DOPENSSL_NO_ERR、-DOPENSSL_NO_HW 、 -DOPENSSL_NO_OCSP、-DOPENSSL_NO_SHA256 和-DOPENSSL_NO_SHA512 等,去掉不必要的内容可以减少生成库的大小。
    • 若要生成 debug 版本的库和可执行程序加-g 或者 -g3(openssl 中有很多宏,需要调试学习最好加上-g3)。
    • make
    • make test 开始测试,此步骤可选
    • make install
    • openssl 会被安装到/usr/local/openssl 目录,包括头文件目录 include、可执行文件目录 bin、man 在线帮助、库目录 lib 以及配置文件目录(ssl)

     源代码

    • openssl 源代码主要由ssl 库、工具源码、范例源码以及测试源码组成。

    crypto源代码

    • 包括如下内容:
    • 1) asn.1 DER 编码解码(crypto/asn1 目录),它包含了基本 asn1 对象的编解码以及数字证书请求、数字证书、CRL撤销列表以及PKCS8等最基本的编解码函数。这些函数主要通过宏来实现。
    • 2)抽象 IO(BIO,crypto/bio 目录),本目录下的函数对各种输入输出进行抽象,包括 文件、内存、标准输入输出、socket和 SSL 协议等。
    • 3)大数运算(crypto/bn 目录),本目录下的文件实现了各种大数运算。这些大数运 算主要用于非对称算法中密钥生成以及各种加解密操作。另外还为用户提供了大量辅助函数,比如内存与大数之间的相互转换。
    • 4)字符缓存操作(crypto/buffer 目录)。
    • 5)配置文件读取(crypto/conf 目录),openssl 主要的配置文件为 openssl.cnf。本目录下的函数实现了对这种格式配置文件的读取操作。
    • 6) DSO(动态共享对象,crypto/dso 目录),本目录下的文件主要抽象了各种平台的动态库加载函数,为用户提供统一接口。
    • 7) 硬件引擎(crypto/engine 目录),硬件引擎接口。用户如果要写自己的硬件引擎, 必须实现它所规定的接口。
    • 8) 错误处理(crypto/err 目录),当程序出现错误时,openssl 能以堆栈的形式显示各 个错误。本目录下只有基本的错误处理接口,具体的的错误信息由各个模块提供。各个模块专门用于错误处理的文件一般为*_err..c 文件。
    • 9) 对称算法、非对称算法及摘要算法封装(crypto/evp 目录)。
    • 10) HMAC(crypto/hmac 目录),实现了基于对称算法的 MAC。
    • 11) hash 表(crypto/lhash 目录),实现了散列表数据结构。openssl 中很多数据结构都是以散列表来存放的。比如配置信息、ssl session 和 asn.1 对象信息等。
    • 12) 数字证书在线认证(crypto/ocsp 目录),实现了 ocsp 协议的编解码以及证书 有效性计算等功能。
    • 13) PEM 文件格式处理(crypto/pem),用于生成和读取各种 PEM 格式文件, 包括各种密钥、数字证书请求、数字证书、PKCS7消息和PKCS8消息等。
    • 14) pkcs7 消息语法(crypto/pkcs7 目录),主要实现了构造和解析 PKCS7 消息;
    • 15) pkcs12 个人证书格式(crypto/pckcs12 目录),主要实现了 pkcs12 证书的构造和解析。
    • 16) 队列(crypto/pqueue 目录),实现了队列数据结构,主要用于 DTLS。  未找到
    • 17) 随机数(crypto/rand 目录),实现了伪随机数生成,支持用户自定义随机数 生成。
    • 18) 堆栈(crypto/stack 目录),实现了堆栈数据结构。 
    • 19) 线程支持(crypto/threads),openssl 支持多线程,但是用户必须实现相关接口。未找到
    • 20) 文本数据库(crypto/txt_db 目录)。
    • 21) x509 数字证书(crypto/x509 目录和 crypto/x509v3),包括数字证书申请、数字证书和CRL的构造、解析和签名验证等功能了;
    • 22) 对称算法(crypto/aes、crypto/bf、crypto/cast、ccrypto/omp (未找到)和 crypto/des 等目录)。
    • 23) 非对称算法(crypto/dh、crypto/dsa、crypto/ec 和 crypto/ecdh(未找到))。
    • 24) 摘要算法(crypto/md2、crypto/md4、crypto/md5 和 crypto/sha)以及密钥交 换/认证算法(crypto/dh 和 crypto/krb5  (未找到))。 

    SSL 源代码 

    • ssl 库所有源代码在 ssl 目录下,包括了 sslv2、sslv3、tlsv1 和 DTLS 的源代码。各个版本基本上都有客户端源码(*_clnt.c)、服务源码(*_srvr.c)、通用源码(*_both.c)、底层包源码(*_pkt.c)、方法源码(*_meth.c)以及协议相关的各种密钥计算源码(*_enc.c)等,都很有规律。  存疑,有问题

    工具源码 apps

    • 工具源码主要在 crypto/apps 目录下,默认编译时只编译成 openssl(windows 下为openssl.exe)可执行文件。该命令包含了各种命令工具。此目录下的各个源码可以单独进行编译

    范例源码 

    • 范例源码在 demo 目录下

    engines

    • 另外 engines 目录给出了 openssl 支持的几种硬件的 engines 源码,也可以作为 engine 编写参考。

     test测试源码

    • 测试源码主要在 test 目录下。

     

    展开全文
  • openssl编程教程完全版Openssl编程第一章基础知识81.1对称算法81.2摘要算法91.3公钥算法91.4回调函数11第二章openssl简介132.1openssl简介132.2openssl安装132.2.1linux下的安装132.2.2windows编译与安装142.3...
  • openssl 编程

    2011-06-09 10:21:22
    openssl 编程,初学者可以看看。openssl 编程,初学者可以看看。
  • OpenSSL编程

    2019-05-13 07:11:01
    文章目录 官方文档:https://www.openssl.org/docs/manmaster/man3/

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,656
精华内容 7,062
关键字:

openssl编程