金昌市住房和城乡建设局网站,环保网站建设公司,iis7重启 网站,网站建设 管理参考#xff1a;深入探索 OpenSSL#xff1a;概念、原理、开发步骤、使用方法、使用场景及代码示例 地址#xff1a;https://oneisall.blog.csdn.net/article/details/131489812?spm1001.2014.3001.5502 目录 1. OpenSSL 概念2. OpenSSL 原理3. OpenSSL 开发步骤4. OpenSSL… 参考深入探索 OpenSSL概念、原理、开发步骤、使用方法、使用场景及代码示例 地址https://oneisall.blog.csdn.net/article/details/131489812?spm1001.2014.3001.5502 目录 1. OpenSSL 概念2. OpenSSL 原理3. OpenSSL 开发步骤4. OpenSSL 使用方法5. OpenSSL 应用场景pdf教程代码 当涉及到网络通信和数据传输的安全性时OpenSSL 是一个非常重要的工具和库。它是一个开源软件包提供了广泛的加密和安全功能。在本博客中我们将详细介绍 OpenSSL 的概念、原理、开发步骤、使用方法、使用场景并结合代码示例进行说明。
1. OpenSSL 概念
OpenSSL 是一个用于实现安全通信的软件包它由一组密码学函数库组成。它的主要目标是通过使用公开的密码学算法来保护数据的机密性、完整性和身份验证。它支持对称加密、非对称加密、数字签名、证书管理等功能。
2. OpenSSL 原理
OpenSSL 采用了多种密码学算法和协议来实现其安全功能。它支持各种对称密码算法如 AES、DES 和 Blowfish用于加密和解密数据。此外它还支持非对称密码算法如 RSA 和 DSA用于生成公钥和私钥并进行数字签名和验证。OpenSSL 还支持 SSL/TLS 协议用于在网络通信中建立安全连接。
3. OpenSSL 开发步骤
使用 OpenSSL 进行开发可以分为以下几个步骤
步骤 1: 安装 OpenSSL 首先您需要从 OpenSSL 官方网站上下载免费提供并安装 OpenSSL 软件包。根据您的操作系统和环境选择相应的版本进行安装。
步骤 2: 包含头文件 在代码中包含 OpenSSL 的头文件以便能够使用其中的函数和数据结构。例如在 C 语言中可以使用以下语句进行包含
#include openssl/ssl.h步骤 3: 初始化 OpenSSL 在使用 OpenSSL 之前需要进行初始化设置。通过调用 SSL_library_init() 函数来初始化 SSL 库。
SSL_library_init();步骤 4: 创建 SSL 上下文 要建立一个安全连接需要创建一个 SSL 上下文对象该对象将存储有关加密和身份验证等设置。您可以使用以下代码片段创建一个 SSL 上下文
SSL_CTX *ctx SSL_CTX_new(SSLv23_client_method());步骤 5: 加载证书和私钥 如果您要在服务器端使用 OpenSSL您需要加载服务器的数字证书和私钥。可以使用以下代码片段进行加载
SSL_CTX_use_certificate_file(ctx, server.crt, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, server.key, SSL_FILETYPE_PEM);步骤 6: 建立安全连接 使用 SSL 上下文对象可以建立与另一端的安全连接。对于服务器端可以使用以下代码片段
SSL *ssl SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
SSL_accept(ssl);对于客户端可以使用以下代码片段
SSL *ssl SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
SSL_connect(ssl);步骤 7: 数据传输和处理 一旦安全连接建立成功就可以在连接上进行数据传输和处理。您可以使用 SSL_read() 和 SSL_write() 函数来读取和写入数据。
char buf[1024];
int len SSL_read(ssl, buf, sizeof(buf));步骤 8: 关闭连接 最后在完成数据传输后应该关闭 SSL 连接并释放资源。可以使用以下代码片段
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);4. OpenSSL 使用方法
使用 OpenSSL您可以执行许多加密和安全操作。以下是一些常见的 OpenSSL 使用方法的示例 对称加密使用 OpenSSL 命令行工具您可以加密和解密文件。例如可以使用以下命令使用 AES 加密一个文件 openssl enc -aes-256-cbc -salt -in input_file -out output_file 非对称加密您可以使用 OpenSSL 生成 RSA 密钥对并使用公钥加密数据私钥解密数据。例如可以使用以下命令生成 RSA 密钥对openssl genpkey -algorithm RSA -out private.pem 然后使用以下命令加密数据openssl rsautl -encrypt -pubin -inkey public.pem -in input_file -out output_file 数字签名您可以使用 OpenSSL 生成数字签名并验证签名的有效性。例如可以使用以下命令生成签名openssl dgst -sign private.pem -out signature data_file 然后使用以下命令验证签名openssl dgst -verify public.pem -signature signature data_file
5. OpenSSL 应用场景
OpenSSL 在许多领域都有广泛的应用以下是一些常见的应用场景 网络安全OpenSSL 被广泛用于实现 SSL/TLS 协议以确保在互联网上的数据传输的安全性。它可以用于创建安全的网站、虚拟专用网络VPN以及安全电子邮件通信。 证书管理OpenSSL 可以生成和管理数字证书用于身份验证和安全通信。它可以用于签署和验证数字证书并用于创建自签名证书和受信任的证书颁发机构CA。 加密工具OpenSSL 提供了各种加密和解密算法可以用于保护敏感数据。它可以用于加密文件、密码生成器以及实现端到端的加密通信。
总结OpenSSL 是一个功能强大的开源软件包提供了广泛的加密和安全功能。它的概念、原理、开发步骤、使用方法和应用场景都非常丰富。通过使用 OpenSSL您可以保护您的数据和通信确保其机密性、完整性和身份验证。无论是在网络通信还是数据安全方面OpenSSL 都是一个重要的工具和库。
#include stdio.h
#include stdlib.h
#include openssl/ssl.hint main() {// 初始化 OpenSSLSSL_library_init();// 创建 SSL 上下文SSL_CTX *ctx SSL_CTX_new(SSLv23_client_method());if (ctx NULL) {printf(Failed to create SSL context.\n);return 1;}// 加载服务器证书if (SSL_CTX_use_certificate_file(ctx, server.crt, SSL_FILETYPE_PEM) ! 1) {printf(Failed to load server certificate.\n);SSL_CTX_free(ctx);return 1;}// 加载服务器私钥if (SSL_CTX_use_PrivateKey_file(ctx, server.key, SSL_FILETYPE_PEM) ! 1) {printf(Failed to load server private key.\n);SSL_CTX_free(ctx);return 1;}// 创建 SSL 对象SSL *ssl SSL_new(ctx);if (ssl NULL) {printf(Failed to create SSL object.\n);SSL_CTX_free(ctx);return 1;}// 设置连接套接字int sockfd socket(AF_INET, SOCK_STREAM, 0);if (sockfd 0) {printf(Failed to create socket.\n);SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 连接服务器struct sockaddr_in server_addr;server_addr.sin_family AF_INET;server_addr.sin_port htons(443);server_addr.sin_addr.s_addr inet_addr(127.0.0.1);if (connect(sockfd, (struct sockaddr*)server_addr, sizeof(server_addr)) 0) {printf(Failed to connect to server.\n);SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 将 SSL 对象绑定到连接套接字SSL_set_fd(ssl, sockfd);// 建立 SSL 连接if (SSL_connect(ssl) 0) {printf(Failed to establish SSL connection.\n);SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 发送数据char message[] Hello, server!;SSL_write(ssl, message, strlen(message));// 接收数据char buffer[1024];SSL_read(ssl, buffer, sizeof(buffer));printf(Received: %s\n, buffer);// 关闭 SSL 连接SSL_shutdown(ssl);SSL_free(ssl);SSL_CTX_free(ctx);return 0;
}上面的示例演示了如何使用 OpenSSL 在客户端建立一个安全连接。首先我们需要初始化 OpenSSL 和创建 SSL 上下文对象。然后加载服务器的证书和私钥。接下来我们创建一个 SSL 对象并将其绑定到连接套接字。通过调用SSL_connect() 建立与服务器的安全连接。然后我们可以使用 SSL_write() 发送数据使用 SSL_read() 接收数据。最后我们关闭 SSL 连接并释放资源。
注这只是一个简单的示例实际的使用场景可能会更复杂。具体的开发步骤和代码实现可能因应用场景而异。在实际开发过程中建议参考 OpenSSL 的官方文档和相关资料以获取更详细的信息和指导。
pdf教程代码
/*************服务端代码**************/
#include stdio.h
#include stdlib.h
#include memory.h
#include errno.h
#ifndef _WIN32
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include netdb.h
#include unistd.h
#else
#include winsock2.h
#include windows.h
#endif
#include pthread.h
#include openssl/rsa.h
#include openssl/crypto.h
#include openssl/x509.h
#include openssl/pem.h
#include openssl/ssl.h
#include openssl/err.h
#define CERTF certs/sslservercert.pem
#define KEYF certs/sslserverkey.pem
#define CAFILE certs/cacert.pem
pthread_mutex_t mlock PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t *lock_cs;
static long *lock_count;
#define CHK_NULL(x) \if ((x) NULL) \{ \printf(null\n); \}
#define CHK_ERR(err, s) \if ((err) -1) \{ \printf( -1 \n); \}
#define CHK_SSL(err) \if ((err) -1) \{ \printf( -1 \n); \}#define CAFILE certs/cacert.pemint verify_callback_server(int ok, X509_STORE_CTX *ctx)
{printf(verify_callback_server \n);return ok;
}int SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx, char *filename, char *pass)
{EVP_PKEY *pkey NULL;BIO *key NULL;key BIO_new(BIO_s_file());BIO_read_filename(key, filename);pkey PEM_read_bio_PrivateKey(key, NULL, NULL, pass);if (pkey NULL){printf(PEM_read_bio_PrivateKey err);return -1;}if (SSL_CTX_use_PrivateKey(ctx, pkey) 0){printf(SSL_CTX_use_PrivateKey err\n);return -1;}BIO_free(key);return 1;
}
static int s_server_verify SSL_VERIFY_NONE;void *thread_main(void *arg)
{SOCKET s, AcceptSocket;WORD wVersionRequested;WSADATA wsaData;struct sockaddr_in service;int err;size_t client_len;SSL_CTX *ctx;SSL *ssl;X509 *client_cert;char *str;char buf[1024];SSL_METHOD *meth;ssl (SSL *)arg;s SSL_get_fd(ssl); // SSL_get_fderr SSL_accept(ssl); // SSL_acceptif (err 0){printf(ssl accerr\n);return;}printf(SSL connection using %s\n, SSL_get_cipher(ssl));client_cert SSL_get_peer_certificate(ssl);if (client_cert ! NULL){printf(Client certificate:\n);str X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);CHK_NULL(str);printf(\t subject: %s\n, str);OPENSSL_free(str);str X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);CHK_NULL(str);printf(\t issuer: %s\n, str);OPENSSL_free(str);X509_free(client_cert);}else{printf(Client does not have certificate.\n);}memset(buf, 0, 1024);err SSL_read(ssl, buf, sizeof(buf) - 1); // SSL_readif (err 0){printf(ssl read err\n);closesocket(s);return;}printf(get : %s\n, buf);
#if 0
buf[err] \0; // SSL_write
err SSL_write (ssl, I hear you., strlen(I hear you.)); CHK_SSL(err);
#endifSSL_free(ssl);closesocket(s);
}pthread_t pthreads_thread_id(void)
{pthread_t ret;ret pthread_self();return (ret);
}void pthreads_locking_callback(int mode, int type, char *file,int line)
{if (mode CRYPTO_LOCK){pthread_mutex_lock((lock_cs[type]));lock_count[type];}else{pthread_mutex_unlock((lock_cs[type]));}
}/*
SSL_CTX数据结构主要用于SSL 握手前的环境准备,设置CA 文件和目录、设置SSL 握手中的证书文件和私钥、设置协议版本以及其他一些SSL 握手时的选项;
SSL数据结构主要用于SSL 握手以及传送应用数据;
SSL_SESSION中保存了主密钥、session id、读写加解密钥、读写MAC 密钥等信息;
SSL_CTX 中缓存了所有SSL_SESSION 信息,SSL 中包含SSL_CTX。
*/
int main()
{int err;int i;SOCKET s, AcceptSocket;WORD wVersionRequested;WSADATA wsaData;struct sockaddr_in service;pthread_t pid;size_t client_len;SSL_CTX *ctx; SSL *ssl;X509 *client_cert;char *str;char buf[1024];SSL_METHOD *meth;SSL_load_error_strings();SSLeay_add_ssl_algorithms();meth SSLv3_server_method();ctx SSL_CTX_new(meth);if (!ctx){ERR_print_errors_fp(stderr);exit(2);}if ((!SSL_CTX_load_verify_locations(ctx, CAFILE, NULL)) ||(!SSL_CTX_set_default_verify_paths(ctx))){printf(err\n);exit(1);}if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) 0){ERR_print_errors_fp(stderr);exit(3);}if (SSL_CTX_use_PrivateKey_file_pass(ctx, KEYF, 123456) 0){ERR_print_errors_fp(stderr);exit(4);}if (!SSL_CTX_check_private_key(ctx)){fprintf(stderr, Private key does not match the certificate public key\n);exit(5);}s_server_verify SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |SSL_VERIFY_CLIENT_ONCE;SSL_CTX_set_verify(ctx, s_server_verify, verify_callback_server);SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAFILE));wVersionRequested MAKEWORD(2, 2);err WSAStartup(wVersionRequested, wsaData);if (err ! 0){printf(err\n);return -1;}s socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // socket第一步if (s 0){return -1;}service.sin_family AF_INET;service.sin_addr.s_addr inet_addr(127.0.0.1);service.sin_port htons(1111);if (bind(s, (SOCKADDR *)service, sizeof(service)) SOCKET_ERROR) // bind{printf(bind() failed.\n);closesocket(s);return -1;}if (listen(s, 1) SOCKET_ERROR) // listen{printf(Error listening on socket.\n);}printf(recv .....\n);lock_cs OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));lock_count OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));for (i 0; i CRYPTO_num_locks(); i){lock_count[i] 0;pthread_mutex_init((lock_cs[i]), NULL);}// 多线程需要设置的两个回调函数CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);while (1){struct timeval tv;fd_set fdset;tv.tv_sec 1;tv.tv_usec 0;FD_ZERO(fdset);FD_SET(s, fdset);select(s 1, fdset, NULL, NULL, (struct timeval *)tv);if (FD_ISSET(s, fdset)){AcceptSocket accept(s, NULL, NULL); // acceptssl SSL_new(ctx); // SSL_newCHK_NULL(ssl);err SSL_set_fd(ssl, AcceptSocket); // SSL_set_fdif (err 0){err pthread_create(pid, NULL, thread_main, (void *)ssl);pthread_detach(pid);}elsecontinue;}}SSL_CTX_free(ctx);return 0;
}/**************客户端代码**************/
#include stdio.h
#include memory.h
#include errno.h
#ifndef _WIN32
#include sys/types.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include netdb.h
#include unistd.h
#else
#include windows.h
#endif
#include pthread.h
#include openssl/crypto.h
#include openssl/x509.h
#include openssl/pem.h
#include openssl/ssl.h
#include openssl/err.h
#define MAX_T 1000
#define CLIENTCERT certs/sslclientcert.pem
#define CLIENTKEY certs/sslclientkey.pem
#define CAFILE certs/cacert.pem
static pthread_mutex_t *lock_cs;
static long *lock_count;pthread_t pthreads_thread_id(void)
{pthread_t ret;ret pthread_self();return (ret);
}
void pthreads_locking_callback(int mode, int type, char *file,int line)
{if (mode CRYPTO_LOCK){pthread_mutex_lock((lock_cs[type]));lock_count[type];}else{pthread_mutex_unlock((lock_cs[type]));}
}
int verify_callback(int ok, X509_STORE_CTX *ctx)
{printf(verify_callback\n);return ok;
}
int SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx, char *filename, char *pass)
{EVP_PKEY *pkey NULL;BIO *key NULL;key BIO_new(BIO_s_file());BIO_read_filename(key, filename);pkey PEM_read_bio_PrivateKey(key, NULL, NULL, pass);if (pkey NULL){printf(PEM_read_bio_PrivateKey err);return -1;}if (SSL_CTX_use_PrivateKey(ctx, pkey) 0){printf(SSL_CTX_use_PrivateKey err\n);return -1;}BIO_free(key);return 1;
}void *thread_main(void *arg)
{int err, buflen, read;int sd;SSL_CTX *ctx (SSL_CTX *)arg;struct sockaddr_in dest_sin;SOCKET sock;PHOSTENT phe;WORD wVersionRequested;WSADATA wsaData;SSL *ssl;X509 *server_cert;char *str;char buf[1024];SSL_METHOD *meth;FILE *fp;wVersionRequested MAKEWORD(2, 2);err WSAStartup(wVersionRequested, wsaData);if (err ! 0){printf(WSAStartup err\n);return -1;}sock socket(AF_INET, SOCK_STREAM, 0); // socket第一步dest_sin.sin_family AF_INET;dest_sin.sin_addr.s_addr inet_addr(127.0.0.1);dest_sin.sin_port htons(1111);
again:err connect(sock, (PSOCKADDR)dest_sin, sizeof(dest_sin)); // connectif (err 0){Sleep(1);goto again;}ssl SSL_new(ctx); // SSL_newif (ssl NULL){printf(ss new err\n);return;}SSL_set_fd(ssl, sock); //SSL_connecterr SSL_connect(ssl);if (err 0){printf(SSL_connect err\n);return;}printf(SSL connection using %s\n, SSL_get_cipher(ssl));server_cert SSL_get_peer_certificate(ssl);printf(Server certificate:\n);str X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0);printf(\t subject: %s\n, str);OPENSSL_free(str);str X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0);printf(\t issuer: %s\n, str);OPENSSL_free(str);X509_free(server_cert);err SSL_write(ssl, Hello World!, strlen(Hello World!)); // SSL_writeif (err 0){printf(ssl write err\n);return;}
#if 0
memset(buf,0,ONE_BUF_SIZE);
err SSL_read (ssl, buf, sizeof(buf) - 1); // SSL_read
if(err0)
{
printf(ssl read err\n);
return ;
}
buf[err] \0;
printf (Got %d chars:%s\n, err, buf);
#endifSSL_shutdown(ssl); /* send SSL/TLS close_notify */SSL_free(ssl);closesocket(sock);
}int main()
{int err, buflen, read;int sd;struct sockaddr_in dest_sin;SOCKET sock;PHOSTENT phe;WORD wVersionRequested;WSADATA wsaData;SSL_CTX *ctx;SSL *ssl;X509 *server_cert;char *str;char buf[1024];SSL_METHOD *meth;int i;pthread_t pid[MAX_T];SSLeay_add_ssl_algorithms();meth SSLv3_client_method();SSL_load_error_strings();ctx SSL_CTX_new(meth);if (ctx NULL){printf(ssl ctx new eer\n);return -1;}if (SSL_CTX_use_certificate_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM) 0){ERR_print_errors_fp(stderr);exit(3);}if (SSL_CTX_use_PrivateKey_file_pass(ctx, CLIENTKEY, 123456) 0){ERR_print_errors_fp(stderr);exit(4);}lock_cs OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));lock_count OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));for (i 0; i CRYPTO_num_locks(); i){lock_count[i] 0;pthread_mutex_init((lock_cs[i]), NULL);}// 多线程需要设置的两个回调函数CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);for (i 0; i MAX_T; i){err pthread_create((pid[i]), NULL, thread_main, (void *)ctx);if (err ! 0){printf(pthread_create err\n);continue;}}for (i 0; i MAX_T; i){pthread_join(pid[i], NULL);}SSL_CTX_free(ctx);printf(test ok\n);return 0;
}