我有一个证书,我需要在http请求的头中发送。我是这样获得证书的:
PCCERT_CONTEXT cert = nullptr;
wstring store = // store name
wstring subjectName = // subject name
HCERTSTORE hStoreHandle = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
store.c_str());
cert = CertFindCertificateInStore(
hStoreHandle,
X509_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR,
subjectName.c_str(),
NULL);
我需要将其作为自定义标头发送,因为位于我的服务前面的负载均衡器在转发请求之前剥离了证书标头["X-ARR-CLIENTCERT"]。我认为我需要发送证书->pbCertEncoded,但在服务器上,我无法解码它并将其转换回X509Certificate2。
这是我在客户端尝试的:
request.headers().add("client-cert", cert->pbCertEncoded);
服务器端:
var headerCert = Request.Headers["client-cert"];
byte[] certdata = Convert.FromBase64String(headerCert);
X509Certificate2 cert = new X509Certificate2(certdata);
服务器上的请求头是非空的。但是它不能解析回X509Certificate2。
我在客户端尝试了另一种方法。获得证书后,我将其转换为字符串
DWORD size = 0;
CryptBinaryToString(cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_STRING_BASE64, NULL, &size);
LPWSTR outstring = new TCHAR[size];
CryptBinaryToString(cert->pbCertEncoded, cert->cbCertEncoded, CRYPT_STRING_BASE64, outstring, &size);
如果我尝试在报头中发送outstring,它会报错:
WinHttpAddRequestHeaders: 87: The parameter is incorrect.
但是当我获取outstring的内容并尝试在服务器上解析它时,它会解码回正确的证书。这告诉我,当在头中传递cert->pbCertEncoded时,我没有做正确的事情。也许我需要重新编码或转换,以便服务器能够正确解析?我很感激任何帮助。谢谢!
我的客户端是在c++和服务器在。net。我使用cpprestsdk在http请求中发送证书。
pbCertEncoded
为ASN。1编码证书的表示。例如:
所以你必须将字节编码为base64,例如:
#include <Wincrypt.h>
#pragma comment (lib, "Crypt32.lib")
int ToBase64Crypto(const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst )
{
DWORD nLenOut = nLenDst;
BOOL fRet = CryptBinaryToString(
(const BYTE*)pSrc,
nLenSrc,
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
pDst, &nLenOut
);
if (!fRet) {
nLenOut=0; // failed
}
return (nLenOut);
}