Table of Contents
1.生成服务器证书和私钥
生成证书和私钥
生成的证书和私钥长这样
2.服务端代码
3.客户端代码
4.编译
文件结构
CMakeLists.txt
编译
运行
参考
openssl req -newkey rsa:2048 -nodes -keyout serverKey.pem \
-x509 -days 365 -out serverCert.cer \
-subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=hijk/emailAddress=132456.com"
$ openssl req -newkey rsa:2048 -nodes -keyout serverKey.pem \
> -x509 -days 365 -out serverCert.cer \
> -subj "/C=CN/ST=GD/L=GZ/O=abc/OU=defg/CN=hijk/emailAddress=132456.com"
Generating a RSA private key
.........+++++
...............................................+++++
writing new private key to 'serverKey.pem'
-----
$ more serverCert.cer
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIUeQ0DpTmzD9WraL0rItBuDM3zwyYwDQYJKoZIhvcNAQEL
BQAwbjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJHWjEMMAoG
A1UECgwDYWJjMQ0wCwYDVQQLDARkZWZnMQ0wCwYDVQQDDARoaWprMRkwFwYJKoZI
hvcNAQkBFgoxMzI0NTYuY29tMB4XDTE5MDgxMTA3MjEzNVoXDTIwMDgxMDA3MjEz
NVowbjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJHWjEMMAoG
A1UECgwDYWJjMQ0wCwYDVQQLDARkZWZnMQ0wCwYDVQQDDARoaWprMRkwFwYJKoZI
hvcNAQkBFgoxMzI0NTYuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAx8p1WVJcY9PXW/ytv60J15VuCs1YN5Va2e2ziRX8c82cjREYp9O/evQch3WZ
hUOEgERGPPwxAtk8lrcap7MAj1wVzgQGfNhvoPjt6PocWN+F9eduIpw+k0RxuPxS
3uZh1e308z7bOmFqCfb0iV94yLbIv1TvXoe8avr8gKmYOrVswvI8ccbkm5EENTKF
dQ+ggYifiUfevsn7Jk6RzPrZIvzqMuRIojkK3Fy/g+vBPhy53j8D92PHl3caX0uF
7Bw/se+lnANltLzT0EUevQpNZhzap9opxQNdGjzFxUe5tVOpXbHocsbvbrrSqHCq
19rWTyrSLSsucu0fjO/0287dVQIDAQABo1MwUTAdBgNVHQ4EFgQUO+GEl5OsSd2B
l6BYRAW/fUJHKEgwHwYDVR0jBBgwFoAUO+GEl5OsSd2Bl6BYRAW/fUJHKEgwDwYD
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAGa+pIBJ7PDzpSl5SycOO
knmE8A2DmuS/bBy9D4qewPgwA2Td8MOY4Jg6/rDvHA82nm5KHc4n5IGNO0MAl1+K
PtB7RJDkfpf6n631bUdQAOUSQCIyT/agLNDuqz6cRgZ26UU5gC/2eFsFp1Xvtia4
EljfOvY8SdJR0s6siYcJZt9LN402rWsMPvdxgy1ySQTkbQsfOnXXpvxqKTo29Chj
/OE9FEyeEi0k7PqAIhiG0a0uV/3HJbXptHuQTqBjMHu0n+dIBrLzTLc0nx9r1mOY
JeLkH4mdpIMdNPDVB9iuwqr3sPohQWnZ72cowFExYuotLBIFZo5mja3ZASV+KUyf
HA==
-----END CERTIFICATE-----
$ more serverKey.pem
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHynVZUlxj09db
/K2/rQnXlW4KzVg3lVrZ7bOJFfxzzZyNERin07969ByHdZmFQ4SAREY8/DEC2TyW
txqnswCPXBXOBAZ82G+g+O3o+hxY34X1524inD6TRHG4/FLe5mHV7fTzPts6YWoJ
9vSJX3jItsi/VO9eh7xq+vyAqZg6tWzC8jxxxuSbkQQ1MoV1D6CBiJ+JR96+yfsm
TpHM+tki/Ooy5EiiOQrcXL+D68E+HLnePwP3Y8eXdxpfS4XsHD+x76WcA2W0vNPQ
RR69Ck1mHNqn2inFA10aPMXFR7m1U6ldsehyxu9uutKocKrX2tZPKtItKy5y7R+M
7/Tbzt1VAgMBAAECggEBALuuoDBpo2sP7UZ3hs0CA7XmpTo2jsGgZ3lDyB1mbwJm
S8NlJRE7ZKxfN5G00qQSuh04hfbyPiRb6IP4vGx/Rm5l5gHjXCjZtXu1fOEYW5rN
V+2aG6cdudbkPCS3vC2ypIOwBySejpk4O8HioPOPoUqEEu9SHY9i2YhyANPo/Z1f
eGZPEFv2UdqT+zoS9SjqlCcioYw0A18ebBBoDdzhNKnNo+2jchhSo8tmXY8nCeVw
hiZJandmQYjRsChLHRf8f3RH5GQjl5gbQMCqJtV7Rgpcr+9otaYvcrZUXztSWj0+
mLc6MepnO0vu7OfoVtJNI647VLtVAz5754+M3cqL3EECgYEA+GjYmUQ+SxfPGq6v
vHJZHB2lQeE4u1AFjdcgakFx3/693XvxOPbDGlms2fpeeqfTQrJljxCw2deHyBRE
0mHrizTkwDUmJGxAo7kJrsrgMwrzfyRLddfDQUZ0NMUX1ICF3z1PEq9u6+Bsexa9
Tii8sH1vBXzsnDp2CO3XNi65csUCgYEAzeVMYJJUcaziAHygRSNDtXIcMGY1Gsdm
e+jTVo7aXzvdF3zGS4lTu80H8EJZMJiybb3DQcsdUzSc+xITAgztDJbcA4DA2waZ
VVPs/qtrolXLYGlv4tkw2khKunnYcRcLVMhbcf4i1fkSO1CYNcgHnU7WXMJd8DPJ
XdqT+dzAKVECgYBqo2fIc/lh9zibNb6PYW9LmJZm766RCss3ltB9jNa71/nd6OUn
FRewaiq/8LE6am1QxpC+l+Wzvsi1Za4dupeJTQ2eTbKwFCCzqC218bXJc7wQKp6S
WiuiDAK63JlcSkguC320gcdWTyOCu8JMmURXZ6GPc4+Hibk+IAwxYGGQGQKBgQDG
m2WmTeCY2owSriSnLFIWx2C7qwuUrj2ETtz1RM0OSh+FlX1txaT4pdj/f/CquNB8
nSyo3XWHGlxGr3OYacGLgEXwNxVQ8TedIFyed9pWd+27LVmY96pxFITJBdmrlPAA
M1hKSDtwLVbR0ndQgYgezLpoNbEJj9qw5rQQtEjEUQKBgEO6sBnyV1u8DigkPfSJ
cvXwW4NIm9CO7A8OIfxb2daJhjFDjRdg+mQ16sL/jbKusRCQV4huPa1f82xSXIXj
uQxqUVmHNogP5IYtadxjjSBclxHmvhtEYOrHDhY86GeEfmt18FsTZdsafmF7gynl
hu8tyA2hJpK1yqgD5uVyRU/q
-----END PRIVATE KEY-----
/** 文件名: server.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CERTSERVER "serverCert.cer"
#define KEYSERVER "serverKey.pem"
#define CHK_ERR(err, s) if((err) == -1) { perror(s); return -1; }
#define CHK_RV(rv, s) if((rv) != 1) { printf("%s error\n", s); return -1; }
#define CHK_NULL(x, s) if((x) == NULL) { printf("%s error\n", s); return -1; }
#define CHK_SSL(err, s) if((err) == -1) { ERR_print_errors_fp(stderr); return -1;}
int main()
{
int rv, err;
SSL_CTX *ctx = NULL;
const SSL_METHOD *meth = NULL;
int listen_sd;
int accept_sd;
struct sockaddr_in socketAddrServer;
struct sockaddr_in socketAddrClient;
int socketAddrClientLen;
SSL *ssl = NULL;
char buf[4096];
rv = SSL_library_init();
CHK_RV(rv, "SSL_library_init");
meth = TLS_server_method();
ctx = SSL_CTX_new(meth);
CHK_NULL(ctx, "SSL_CTX_new");
rv = SSL_CTX_use_certificate_file(ctx, CERTSERVER, SSL_FILETYPE_PEM);
CHK_RV(rv, "SSL_CTX_use_certicificate_file");
rv = SSL_CTX_use_PrivateKey_file(ctx, KEYSERVER, SSL_FILETYPE_PEM);
CHK_RV(rv, "SSL_CTX_use_PrivateKey_file");
rv = SSL_CTX_check_private_key(ctx);
CHK_RV(rv, "SSL_CTX_check_private_key");
listen_sd = socket(AF_INET, SOCK_STREAM, 0);
CHK_ERR(listen_sd, "socket");
memset(&socketAddrServer, 0, sizeof(socketAddrServer));
socketAddrServer.sin_family = AF_INET;
socketAddrServer.sin_port = htons(8443);
socketAddrServer.sin_addr.s_addr = INADDR_ANY;
err = bind(listen_sd, (struct sockaddr *)&socketAddrServer,
sizeof(socketAddrServer));
CHK_ERR(err, "bind");
err = listen(listen_sd, 5);
CHK_ERR(err, "listen");
socketAddrClientLen = sizeof(socketAddrClient);
accept_sd = accept(listen_sd, (struct sockaddr *)&socketAddrClient,
&socketAddrClientLen);
CHK_ERR(accept_sd, "accept");
close(listen_sd);
printf("Connect to %s, port 0x%04X(=%d)\n",
inet_ntoa(socketAddrClient.sin_addr),
(int)ntohs(socketAddrClient.sin_port),
(int)ntohs(socketAddrClient.sin_port));
ssl = SSL_new(ctx);
CHK_NULL(ssl, "SSL_new");
rv = SSL_set_fd(ssl, accept_sd);
CHK_RV(rv, "SSL_set_fd");
rv = SSL_accept(ssl);
CHK_RV(rv, "SSL_accpet");
rv = SSL_read(ssl, buf, sizeof(buf) - 1);
CHK_SSL(rv, "SSL_read");
buf[rv] = '\0';
printf("Got %d chars :%s\n", rv, buf);
rv = SSL_write(ssl, "I accept your request", strlen("I accept your request"));
CHK_SSL(rv, "SSL_write");
close(accept_sd);
SSL_free(ssl);
SSL_CTX_free(ctx);
return 0;
}
/** 文件名: client.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CHK_ERR(err, s) if((err) == -1) { perror(s); return -1; }
#define CHK_RV(rv, s) if((rv) != 1) { printf("%s error\n", s); return -1; }
#define CHK_NULL(x, s) if((x) == NULL) { printf("%s error\n", s); return -1; }
#define CHK_SSL(err, s) if((err) == -1) { ERR_print_errors_fp(stderr); return -1;}
int main()
{
int rv;
int err;
int client_fd;
struct sockaddr_in socketAddrClient;
const SSL_METHOD *meth = NULL;
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
char buf[4096];
rv = SSL_library_init();
CHK_RV(rv, "SSL_library_init");
meth = TLS_client_method();
ctx = SSL_CTX_new(meth);
CHK_NULL(ctx, "SSL_CTX_new");
client_fd = socket(AF_INET, SOCK_STREAM, 0);
CHK_ERR(client_fd, "socket");
memset(&socketAddrClient, 0, sizeof(socketAddrClient));
socketAddrClient.sin_family = AF_INET;
socketAddrClient.sin_port = htons(8443);
socketAddrClient.sin_addr.s_addr = inet_addr("127.0.0.1");
err = connect(client_fd, (struct sockaddr *)&socketAddrClient,
sizeof(socketAddrClient));
CHK_ERR(err, "connect");
ssl = SSL_new(ctx);
CHK_NULL(ssl, "SSL_new");
rv = SSL_set_fd(ssl, client_fd);
CHK_RV(rv, "SSL_set_fd");
rv = SSL_connect(ssl);
CHK_RV(rv, "SSL_connect");
rv = SSL_write(ssl, "Hello, I am the client", strlen("Hello, I am the client"));
CHK_SSL(rv, "SSL_write");
rv = SSL_read(ssl, buf, sizeof(buf) - 1);
CHK_SSL(rv, "SSL_read");
buf[rv] = '\0';
printf("Got %d chars :%s\n", rv, buf);
SSL_shutdown(ssl);
close(client_fd);
SSL_free(ssl);
SSL_CTX_free(ctx);
return 0;
}
$ tree -d
.
└── src
├── client
└── server
cmake_minimum_required(VERSION 3.1)
project(demo1 LANGUAGES C)
aux_source_directory(./src/client client_SOURCES)
aux_source_directory(./src/server server_SOURCES)
add_executable(client ${client_SOURCES})
add_executable(server ${server_SOURCES})
set_property(TARGET client PROPERTY C_STANDARD 11)
set_property(TARGET server PROPERTY C_STANDARD 11)
find_package(OpenSSL REQUIRED)
target_include_directories(client PRIVATE ${OPENSSL_INCLUDE_DIR})
target_include_directories(server PRIVATE ${OPENSSL_INCLUDE_DIR})
target_link_libraries(client PRIVATE
${OPENSSL_LIBRARIES}
)
target_link_libraries(server PRIVATE
${OPENSSL_LIBRARIES}
)
$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Toa/openssl-demo-work20190606/ssl-demo
$ make
[ 25%] Building C object CMakeFiles/client.dir/src/client/client.c.o
[ 50%] Linking C executable client.exe
[ 50%] Built target client
[ 75%] Building C object CMakeFiles/server.dir/src/server/server.c.o
[100%] Linking C executable server.exe
[100%] Built target server
窗口1:
$ ./server.exe
Connect to 127.0.0.1, port 0xD106(=53510)
Got 22 chars :Hello, I am the client
窗口2:
$ ./client.exe
Got 21 chars :I accept your request
博文:https://blog.csdn.net/oj847935591/article/details/79362542
源码地址:https://github.com/liuqun/openssl-demo
感谢GitHub序友:liuqun