Windows使用mkcert颁发证书及应用

项目场景:

开发一个web服务端,在本地电脑运行,网页可以通过http/https去访问:

服务端程序


问题描述:

如果网页通过https去访问,浏览器会提示非安全链接:

网页通过https访问


原因分析:

服务端没有证书,需要使用自签证书,然后在服务端中使用自签证书。


解决方案:

可以使用mkcert颁发证书,步骤如下:
1、点击下载mkcert.exe,或者GitHub下载,选择mkcert-v1.4.3-windows-amd64.exe:

mkcert.exe

2、生成根证书,cmd执行mkcert-v1.4.3-windows-amd64.exe -install,在C:\Users\zdp\AppData\Local\mkcert中生成根证书,将该根证书安装在需要访问web服务端的电脑上。安装证书可以直接双击rootCA.crt:

根证书

也可以运行下面的命令:

安装命令

可以看到本地电脑证书已经安装完成:

查看已安装的证书

3、为服务端颁发证书,cmd执行mkcert-v1.4.3-windows-amd64.exe 127.0.0.1,会生成证书,用于服务端:

服务端证书

服务端代码片段:

#include "openssl/ssl.h"
#include "openssl/err.h"

#define SERVER_ADDR "127.0.0.1"  // 服务器地址
#define SERVER_PORT 53989
#define SSL_CERT_FILE "server-cert.pem"
#define SSL_KEY_FILE  "server-key.pem"

SSL_CTX *m_sslCtx;
SOCKET m_sock_ssl;
SOCKET m_sock_ssl_ipv6;

int InitSSLServer() {
    // SSL 库初始化
    SSL_library_init();
    // 载入所有 SSL 算法
    OpenSSL_add_all_algorithms();
    // 载入所有 SSL 错误消息
    SSL_load_error_strings();
    // 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text
    // 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准
    m_sslCtx = SSL_CTX_new(SSLv23_server_method());
    if (m_sslCtx == NULL) {
        OutputDebugStringA("Couldn't create the SSL method.");
        return -1;
    }
    // 载入用户的数字证书, 此证书用来发送给客户端。证书里包含有公钥
    if (SSL_CTX_use_certificate_file(m_sslCtx, SSL_CERT_FILE, SSL_FILETYPE_PEM) <= 0) {
        OutputDebugStringA("Failure reading SSL certificate file.");
        return -1;
    }
    // 载入用户私钥
    if (SSL_CTX_use_PrivateKey_file(m_sslCtx, SSL_KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
        OutputDebugStringA("Failure reading private key file.");
        return -1;
    }
    // 检查用户私钥是否正确
    if (!SSL_CTX_check_private_key(m_sslCtx)) {
        OutputDebugStringA("Private key does not match the certificate public key.");
        return -1;
    }

    // 创建套接字
    m_sock_ssl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_sock_ssl == INVALID_SOCKET) {
        OutputDebugStringA("Create m_sock_ssl failed.");
        return -1;
    }
    // 绑定端口
    int port = -1;
    if ((port = BindPort(m_sock_ssl, SERVER_PORT + 1)) == -1) {
        OutputDebugStringA("m_sock_ssl socket bind failed.");
        return -1;
    }
    // 开始监听
    if (listen(m_sock_ssl, 300) != 0) {
        OutputDebugStringA("m_sock_ssl socket listen failed.");
        return -1;
    }

    // 初始化IPV6 ssl socket
    m_sock_ssl_ipv6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
    if (m_sock_ssl_ipv6 != INVALID_SOCKET) {
        if (BindPort(m_sock_ssl_ipv6, port, true) != -1) {  // 和IPV4使用同一个端口
            listen(m_sock_ssl_ipv6, 300);
        }
    } else {
        OutputDebugStringA("IPV6 ssl socket Create failed.");
    }

    OutputDebugStringA("SSL security server initialization is complete!");
    return 0;
}

之后再访问web服务端就是安全链接了(火狐浏览器不支持):

安全的访问

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值