系统管理Visual C++ 7.1Visual C++ 8.0Visual C++ 7.0C++/CLIWin32Visual C++ 6.0MFCC中级开发Visual StudioWindowsC++
使用 WinHTTP 进行一次性 SSL 证书注册






4.53/5 (8投票s)
从远程网页浏览器注册自签名 SSL 证书。
引言
你是否曾经需要从“远程”网页浏览器中将自签名证书安装到 IE 证书缓存中?这里有一些示例代码,或许可以使事情变得更容易。
背景
HTTPS 测试通常会很麻烦。每次浏览到你的测试 Web 服务器时,都会出现一个挑战对话框,SSL 证书已过期等等。接下来,你希望其他人测试你的应用程序。理想情况下,他们可以运行一个自注册程序来简化操作。
使用代码
代码很简单。步骤也很简单。打开到 Web 服务器的 HTTPS 连接,获取 SSL 证书,并将证书安装到证书缓存中。提供的代码依赖于 Windows HTTP Services 接口以及一些 Cryptography API 调用。函数 CwinHttpsCertDlg::Register()
打开一个 WinHTTP 会话,创建连接并发送请求。此时,我们查询请求以获取证书。然后将证书放置在证书存储区中。
注意:为了这个示例代码的需要,证书被放置在“根”存储区中。请小心将证书添加到你的缓存中,并在测试完成后将其删除。保护你的密钥!
以下是一些从 Web 服务器“获取”证书的代码片段
DWORD dwFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID| SECURITY_FLAG_IGNORE_UNKNOWN_CA; // open a session handle hSession = WinHttpOpen( szUserAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); // connect to a web server hConnect = WinHttpConnect( hSession, m_csServer, INTERNET_DEFAULT_HTTPS_PORT, 0 ); // open a request handle hRequest = WinHttpOpenRequest( hConnect, L"GET", L"", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE ); // important - set security to ignore 'bad' certs bRet = WinHttpSetOption( hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(DWORD) ); // send the request bRet = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); // get a handle on the certificate bRet = WinHttpQueryOption( hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwLen );
现在我们获得了证书的句柄,将证书加载到存储区中
// open a certificate store hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root"); // add the certificate bRet = CertAddCertificateContextToStore( hCertStore, pCert, CERT_STORE_ADD_REPLACE_EXISTING, NULL ); // release the certificate CertFreeCertificateContext(pCert); // close the store bRet = CertCloseStore( hCertStore, 0 );
最后,你可能可以使用以下脚本生成证书。这是一个带有 OpenSSL 的 *NIX 盒子上的 *bash* 脚本。
#!/bin/bash
#Generate ssl certificate
PREFIX="foxbat.swiftview.com"
#cd /opt/apache/conf
mkdir ssl
cd ssl
openssl genrsa 1024 > ${PREFIX}.key
chmod 600 ${PREFIX}.key
openssl req -new -key ${PREFIX}.key > ${PREFIX}.csr
openssl req -x509 -days 365 -key ${PREFIX}.key -in ${PREFIX}.csr > ${PREFIX}.crt
echo "Add the following lines to httpd.conf"
echo "SSLCertificateFile /opt/apache/conf/ssl/${PREFIX}.crt"
echo "SSLCertificateKeyFile /opt/apache/conf/ssl/${PREFIX}.key"
关注点
这段代码的一个令人烦恼的问题是,Platform SDK 不包含 libs 的 WinHTTP 头文件。你需要安装较新版本的 SDK 才能正确编译此代码。