Openssl Server C Demo
Posted 小米渣的逆袭
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Openssl Server C Demo相关的知识,希望对你有一定的参考价值。
证书生成
rootPath=$(cd "$(dirname "$0")"; pwd)
#删除打包数据目录
OUTPUT=$rootPath/build
rm -drf $OUTPUT
mkdir $OUTPUT
# 生成CA证书
echo "-----------------------------生成CA证书----------------------------------"
name="standard_ca"
openssl genrsa -out $OUTPUT/$name.key 2048
openssl req -new -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
openssl x509 -req -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_ca -signkey $OUTPUT/$name.key -out $OUTPUT/$name.cer
openssl x509 -in $OUTPUT/$name.cer -text -noout
rm -f $OUTPUT/$name.req
echo "-----------------------------Server签名证书----------------------------------"
# Server签名证书
name="standard_server_sign"
openssl genrsa -out $OUTPUT/$name.key 2048
openssl req -new -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
openssl x509 -req -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_req -CA $OUTPUT/standard_ca.cer -CAkey $OUTPUT/standard_ca.key -set_serial 1000000001 -extfile $rootPath/openssl.cnf -out $OUTPUT/$name.cer
openssl x509 -in $OUTPUT/$name.cer -text -noout
rm -f $OUTPUT/$name.req
echo "-----------------------------客户端证书----------------------------------"
# 客户端证书
name="standard_client"
openssl genrsa -out $OUTPUT/$name.key 2048
openssl req -new -key $OUTPUT/$name.key -out $OUTPUT/$name.req -subj /C=CN/ST=JS/L=NJ/O=NJ/CN="127.0.0.1"
openssl x509 -req -days 3650 -in $OUTPUT/$name.req -extfile ./openssl.cnf -extensions v3_req -CA $OUTPUT/standard_ca.cer -CAkey $OUTPUT/standard_ca.key -set_serial 1000000001 -extfile $rootPath/openssl.cnf -out $OUTPUT/$name.cer
openssl x509 -in $OUTPUT/$name.cer -text -noout
rm -f $OUTPUT/$name.req
服务端代码
// HttpSvrDemo.cpp : 定义控制台应用程序的入口点。
//
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"User32.lib")
#pragma comment(lib,"Advapi32.lib")
#pragma comment(lib,"Gdi32.lib")
#include <openssl\\\\ssl.h>
//#pragma comment(lib,"libeay32.lib")
//#pragma comment(lib,"ssleay32.lib")
#pragma warning(disable: 4996)
#define CERTF "C:\\\\Users\\\\wjr\\\\Downloads\\\\standard_server_sign.cer"
#define KEYF "C:\\\\Users\\\\wjr\\\\Downloads\\\\standard_server_sign.key"
#define CA "C:\\\\Users\\\\wjr\\\\Downloads\\\\standard_ca.cer"
// 这是一个 https 服务端 Demo
int main()
WSADATA wsaData;
sockaddr_in service = 0 ;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET AcceptSocket = INVALID_SOCKET;
// 1.初始化 WSA 相关函数
int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\\n", err);
return -1;
// 2.初始化静态库 加载错误字符 加载算法库
SSL_library_init();
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
// 3.绑定本地端口并监听 ---- 摘自 MSDN
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET)
wprintf(L"socket function failed with error: %ld\\n", WSAGetLastError());
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(28801);
int iResult = bind(ListenSocket, (SOCKADDR*)&service, sizeof(service));
if (iResult == SOCKET_ERROR)
wprintf(L"bind function failed with error %d\\n", WSAGetLastError());
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
wprintf(L"listen function failed with error: %d\\n", WSAGetLastError());
wprintf(L"Listening on socket...\\n");
// 4.等待建立连接
while (TRUE)
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET)
wprintf(L"accept failed with error: %ld\\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return -1;
else
wprintf(L"Client connected.\\n");
// 4.1将套接字与证书绑定
const SSL_METHOD* meth = SSLv23_server_method();
SSL_CTX* ctx = SSL_CTX_new(meth);
要求校验对方证书
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
加载CA
if (SSL_CTX_load_verify_locations(ctx, CA, NULL) <= 0)
wprintf(L"SSL_CTX_use_certificate_file failed.\\n");
closesocket(AcceptSocket);
continue;
if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0)
wprintf(L"SSL_CTX_use_certificate_file failed.\\n");
closesocket(AcceptSocket);
continue;
if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0)
wprintf(L"SSL_CTX_use_PrivateKey_file failed.\\n");
closesocket(AcceptSocket);
continue;
if (SSL_CTX_check_private_key(ctx) <= 0)
wprintf(L"Private key does not match the certificate public key\\n");
closesocket(AcceptSocket);
continue;
SSL* ssl = SSL_new(ctx);
SSL_set_fd(ssl, AcceptSocket);
if (SSL_accept(ssl) == -1)
int n = SSL_get_error(ssl, -1);
const char* p1 = SSL_state_string_long(ssl);
printf("错误代码:%s\\r\\n", SSL_state_string_long(ssl));
closesocket(AcceptSocket);
continue;
// 4.2从SSL套接字读取数据
char buf[4096] = 0 ;
int sslRead = SSL_read(ssl, buf, 4095);
printf("%s\\n", buf);
// 4.3往SSL套接字写入数据
char szTemp[400] = "HTTP/1.1 200 OK\\r\\nServer: bfe/1.0.8.14\\r\\nDate: Mon, 29 Feb 2016 06:21:46 GMT\\r\\nContent-Type: text/html\\r\\nContent-Length: 70\\r\\nConnection: keep-alive\\r\\n\\r\\n<html>\\r\\n<head><title>200 Ok</title></head><body> 200 OK </body></html>";
int nCount = strlen(szTemp);
int nRet = 0;
do
nRet += SSL_write(ssl, szTemp, nCount);
if (nRet >= nCount)
break;
while (true);
closesocket(AcceptSocket);
AcceptSocket = INVALID_SOCKET;
closesocket(ListenSocket);
return 0;
以上是关于Openssl Server C Demo的主要内容,如果未能解决你的问题,请参考以下文章
c udp server client demo --待调试