证书生成实操
下面是干什么?
利用openssl,生成一个服务端证书,以便客户端与服务端连接时,客户端可以对服务端的身份进行单向认证。
在本例中我们自己是CA,也是服务端。
- 使用rsa算法生成一个
server.key文件 里边包含一个秘钥对。 在rsa中 既可以公钥加密 私钥解密,也可以私钥解密 公钥加密。
c++
openssl genrsa -out server.key 2048
//如果想从server.key文件中导出公钥和私钥
openssl rsa -in server.key -pubout -out server.pub
openssl rsa -in server.key -out private.key- 生成一个证书请求
server.csr
c++
openssl req -new -key server.key -out server.csr- ca用其私钥对csr证书请求进行签名 生成x509标准证书
server.crt
c++
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt有了CA签名过的crt证书以后,服务端只需要安装该证书,客户端在与服务端进行ssl握手时就可以对服务端的身份进行单向认证了。
证书原理示意图

例子 (Linux下)
下面是干什么?
一个是ssl客户端 一个是ssl服务端 实现https。
两个例子都是camke构建的, 记得在cmake中导入openssl的静态库 libssl 和 libcrypto
cmake
cmake_minimum_required(VERSION 2.6)
project(C_EPOLL_SERVER)
include_directories(${CMAKE_SOURCE_DIR}/include)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_options("-Wall")
set(CMAKE_BUILD_TYPE "Debug")
add_executable(../main src/main.cpp)
target_link_libraries(../main /usr/lib64/libssl.so /usr/lib64/libcrypto.so)1.纯socket和openssl实现https协议的ssl_client访问百度一下。
c++
#include <cstdio>
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <string>
#include <unistd.h>
using namespace std;
int main()
{
//初始化SSL库
SSL_library_init();
SSL_load_error_strings();
//请求百度服务器 443端口
//110.242.68.3是百度ip
std::string server_ip = "110.242.68.3";
short server_port = 443;
int sock = socket(AF_INET, SOCK_STREAM, 0);
cout << "Socket created\n";
// 设置服务器地址和端口
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port); // 服务器端口号
server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str()); // 服务器IP地址
// TCP三次握手
connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
// 创建SSL上下文
//SSLv23_client_method 客户端支持的协议版本 会发送给服务端
//也可以改成TLSv1_1_client_method();
SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
// 创建SSL对象
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
// SSL握手
cout<< SSL_connect(ssl) <<"\n";
// 构造个http请求 并且往对端同步发送
// 加密过的ssl数据
std::string http_rep =
"GET /s?wd=happy HTTP/1.1\r\n"
"Host: "+server_ip+":"+ std::to_string(server_port)+"\r\n"
"Connection: keep-alive\r\n\r\n";
std::cout<<http_rep<<"\n";
SSL_write(ssl, http_rep.c_str(), http_rep.size());
// 同步接收服务端发回的http报文
char http_res[1024];
int len = 0;
int flag = 0;
while((len = SSL_read(ssl, http_res,sizeof(http_res)))> 0){
std::cout<<"reply: " <<std::string(http_res)<<"\n";
}
getchar();
//关闭ssl连接
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
//四次挥手
close(sock);
std::cout<<"\n";
return 0;
}2.tcp_socket和openssl实现ssl_server
c++
#include <functional>
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <string.h>
#include <sys/uio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
using namespace std;
int main()
{
// 初始化OpenSSL库
SSL_library_init();
SSL_load_error_strings();
int sock = socket(AF_INET, SOCK_STREAM, 0);
cout<<"Socket created";
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8083);
addr.sin_addr.s_addr = INADDR_ANY;
cout<< bind(sock,(struct sockaddr*)&addr,sizeof(addr))<<"\n";
cout<< listen(sock, 10) <<"\n";
// 创建SSL上下文
SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
// 加载被CA签名过的服务端证书 (如果没有CA签名,浏览器访问的时候提示不安全)
SSL_CTX_use_certificate_file(ctx, "/root/server.crt", SSL_FILETYPE_PEM);
// 加载服务端私钥
SSL_CTX_use_PrivateKey_file(ctx, "/root/server.key", SSL_FILETYPE_PEM);
struct sockaddr_in cilent_addr;
while (1) {
socklen_t size;
std::cout<<"等待连接"<<"\n";
memset(&cilent_addr,0,sizeof(cilent_addr));
int client_sock = accept(sock, (struct sockaddr*)&cilent_addr, &size);
// 创建SSL对象
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_sock);
// SSL握手(服务端阻塞在这里 等客户端SSL_connect(ssl))
cout<< SSL_accept(ssl)<<"\n";
std::string http_rep = "HTTP/1.1 200 OK\r\n"
"Accept-Ranges: bytes\r\n"
"Cache-Control: no-cache\r\n"
"Connection: keep-alive\r\n\r\n";
std::string html = "<html><body><h1>Welcome</h1></body></html>\r\n\r\n";
SSL_write(ssl, http_rep.c_str(), http_rep.size());
SSL_write(ssl, html.c_str(), html.size());
}
std::cout<<"\n";
return 0;
}常用接口



原理好文
什么是单项加密、对称加密、非对称加密、证书、秘钥、SSL/TLS原理? https://my.oschina.net/helloworldnet/blog/5587819