在官网的下载地址下载zip包并解压
在命令行中输入./config make sudo make install 等待安装完即可。其中需要注意的一行是库文件被复制到哪个文件夹里面了编写一个测试代码test_openssl.c
#include <stdio.h> #include <openssl/evp.h> int main(){ OpenSSL_add_all_algorithms(); return 0; } 注意刚才记下来的库所在路径> gcc -o test_openssl test_openssl.c -L/usr/local/lib(路径) -lcrypto -ldl -lpthread > ./test_openssl > echo $? 研究OpenSSL算法,测试对称算法中的AES,非对称算法中的RSA,Hash算法中的MD5 对称加密:对称加密需要使用的标准命令为 encopenssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id] -in filename:指定要加密的文件存放路径 -out filename:指定加密后的文件存放路径 -salt:自动插入一个随机数作为文件内容加密,默认选项 -e:可以指明一种加密算法,若不指的话将使用默认加密算法 -d:解密,解密时也可以指定算法,若不指定则使用默认算法,但一定要与加密时的算法一致 -a/-base64:使用-base64位编码格式 AES:openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass pass:123456 //密码123456RSA:
RSA 的用法如下: openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin arg] [-out filename] [-passout arg] [-sgckey] [-des] [-des3] [-idea] [-text] [-noout] [-modulus] [-check] [-pubin] [-pubout] [-engine id] 常用选项: -in filename:指明私钥文件 -out filename:指明将提取出的公钥保存至指定文件中 -pubout:根据私钥提取出公钥MD5:
openssl passwd -1 -in test.txt -salt 12345678 生成密码需要使用的标准命令为 passwd ,用法如下: openssl passwd [-crypt] [-1] [-apr1] [-salt string] [-in file] [-stdin] [-noverify] [-quiet] [-table] {password} 常用选项有: -1:使用md5加密算法 -salt string:加入随机数,最多8位随机数 -in file:对输入的文件内容进行加密 -stdion:对标准输入的内容进行加密 在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护 头文件: #include <openssl/ssl.h> #include <openssl/err.h> SSL库初始化 SSL_library_init(); 载入所有 SSL 算法 OpenSSL_add_all_algorithms(); 载入所有 SSL 错误消息 SSL_load_error_strings(); 产生一个 SSL_CTX 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[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); } 基于 ctx 产生一个新的 SSL,并将连接用户的 socket 加入到 SSL ssl = SSL_new(ctx); SSL_set_fd(ssl, new_server_socket_fd); 建立 SSL 连接 if (SSL_accept(ssl) == -1) { perror("accept"); close(new_fd); break; } SSL数据传输 int len = SSL_read(ssl, buffer, MAXBUF); if (len > 0) printf("接收消息成功:'%s',共%d个字节的数据\n", buffer, len); else printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno)); 客户端与服务器传输完数据后,关闭 SSL 连接,释放 SSL SSL_shutdown(ssl); SSL_free(ssl); 释放 CTX SSL_CTX_free(ctx);代码已上传至码云:
#include<netinet/in.h> // sockaddr_in …… #include <openssl/ssl.h> #include <openssl/err.h> …… #include<string.h> // bzero #define SERVER_PORT 8000 #define LENGTH_OF_LISTEN_QUEUE 20 #define BUFFER_SIZE 1024 #define FILE_NAME_MAX_SIZE 512 #define MAX 10000000 #define MAXBUF 1024 int main(void) { // 声明并初始化一个服务器端的socket地址结构 struct sockaddr_in server_addr; …… server_addr.sin_port = htons(SERVER_PORT); SSL_CTX *ctx; //ssl数据结构 /* 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,若成功,返回socket描述符 int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0); …… // 绑定socket和socket地址结构 …… // socket监听 …… while(1) { SSL *ssl; // 定义客户端的socket地址结构 struct sockaddr_in client_addr; socklen_t client_addr_length = sizeof(client_addr); // 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信 // accept函数会把连接到的客户端信息写到client_addr中 int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length); …… /* 基于 ctx 产生一个新的 SSL */ ssl = SSL_new(ctx); /* 将连接用户的 socket 加入到 SSL */ SSL_set_fd(ssl, new_server_socket_fd); /* 建立 SSL 连接 */ if (SSL_accept(ssl) == -1) { perror("accept"); close(new_fd); break; } // recv函数接收数据到缓冲区buffer中 char buffer[BUFFER_SIZE]; bzero(buffer, BUFFER_SIZE); if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0) { perror("Server Recieve Data Failed:"); break; } // 然后从buffer(缓冲区)拷贝到file_name中 int len = SSL_read(ssl, buffer, MAXBUF); if (len > 0) printf("接收消息成功:'%s',共%d个字节的数据\n", buffer, len); else printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno)); char file_name[FILE_NAME_MAX_SIZE+1]; …… // 打开文件并读取文件数据 FILE *fp = fopen(file_name, "r"); if(NULL == fp) { printf("File:%s Not Found\n", file_name); } else { //printf("buffer:%s\n",buffer);//buffer为filename char *argv[]={"wc","-w",file_name,0}; execvp( "wc" ,argv); fclose(fp); /* 关闭 SSL 连接 */ SSL_shutdown(ssl); /* 释放 SSL */ SSL_free(ssl); } // 关闭与客户端的连接 close(new_server_socket_fd); } // 关闭监听用的socket close(server_socket_fd); /* 释放 CTX */ SSL_CTX_free(ctx); return 0; }然后居然就可以了,也不会再报错,可以运行测试代码
本次实验在MAC OS系统下也可以完成,需要特别注意的是静态库动态库的链接,以及头文件的使用,对于OpenSSL的使用我们还不是很熟悉,很多步骤都是一边网上查资料一边百度一边尝试着写的,这也耗费了一些时间,不过网上对于OpenSSL的研究很多,能参考的资料就更丰富了,花时间学习就会有很多收获。
转载于:https://www.cnblogs.com/zhuohua/p/8030486.html
