如何获得序列号的证书十六进制格式字符串使用cryptoapi

How to get Serial number of certificate in hex format string using cryptoapi?

本文关键字:字符串 cryptoapi 格式 十六进制 何获得 序列号 证书      更新时间:2023-10-16

如何使用cryptoapi获得十六进制格式字符串的证书序列号?我试过使用

LPTSTR pszSerial = NULL;
    DWORD cbSerial = 0;
    CryptBinaryToString(pCertContext->pCertInfo->SerialNumber.pbData,pCertContext->pCertInfo->SerialNumber.cbData,CRYPT_STRING_HEX,NULL,&cbSerial);
    pszSerial = new TCHAR[cbSerial];
    CryptBinaryToString(pCertContext->pCertInfo->SerialNumber.pbData,pCertContext->pCertInfo->SerialNumber.cbData,CRYPT_STRING_HEX,pszSerial,&cbSerial);

但结果不是我想要的,我可以得到序列号,但它颠倒了。

我知道这是4年之后的问题被问到,但我得到这个页面很多次,当我正在寻找这个问题的解决方案-所以也许我不是唯一的人,我的答案会帮助别人;)

我发现信息,序列号在结构体_CERT_INFO 中反转,因此certInfo.SerialNumber.pbData的字节应该反转。此外,您应该只占用certInfo.SerialNumber.cbData字节(cbData是序列号的长度)。这很重要,因为当我试图使用整个pbData时,我得到了许多垃圾字节。

当我反转字节时,我将它们转换为十六进制。就这些;)

我代码:

unsigned char* pbData = pCertContext->pCertInfo->SerialNumber.pbData;
int cbData = pCertContext->pCertInfo->SerialNumber.cbData;
std::string serial((char*)pbData);
std::string serialSubstring = serial.substr(0,cbData);
std::reverse(serialSubstring.begin(), serialSubstring.end());
String snInHex(string_to_hex(serialSubstring).c_str());
//now snInHex contains serial number in hexadecimal string

额外功能- serial number作为数字!当您需要序列号作为数据时(例如,创建xades文件):

unsigned int sNumber;
std::stringstream ss;
ss << std::hex << snInHex.c_str();
ss >> sNumber;
//now serial number is stored as number in sNumber

编辑

string_to_hec函数来自这里:c++将字符串转换为十六进制,反之亦然

下面的代码片段显示了如何反转证书序列号。

for( int i = 0 ; i < pCertContext->pCertInfo->SerialNumber.cbData ; i ++ )
{
    CertSerialNo[i] = *( pCertContext->pCertInfo->SerialNumber.pbData 
                            + pCertContext->pCertInfo->SerialNumber.cbData - i - 1 ) ;
}

在我的例子中,string_to_hex不存在。所以,使用下面的转换方法。

DWORD dwData = pSignerInfo->SerialNumber.cbData;
char pszHexChar[4];
std::string lSerialNumber = "";
for (DWORD n = 0; n < dwData; n++)
{
    printf("%02x ", pSignerInfo->SerialNumber.pbData[dwData - (n + 1)]);
    sprintf_s(pszHexChar, sizeof(pszHexChar), "%02x ", pSignerInfo->SerialNumber.pbData[dwData - (n + 1)]);
    std::string lHexChar = pszHexChar + '';
    lSerialNumber = lSerialNumber + lHexChar;
}
printf("%s", lSerialNumber);