CryptAPI 取得 证书序列号 的操作
2012-07-20 10:11
190 查看
CryptAPI 取得 证书序列号 的操作
通过Win32 CryptAPI查找个人证书库(MY)中的指定的证书的序列号。显示之。证书的序列号经过处理,和IE中显示的一样(只是人为地去掉了空格)。
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")
头文件
view plainprint?
// 去除指定字符
// 下面的代码用于字符串替换
static char* trim(char *str, char chr){
return (*str==0)?str:(((*str!=chr)?(((trim(str+1, chr)-1)==str)?str:(*(trim(str+1,chr)-1)=*str,*str=chr,trim(str+1,chr))):trim(str+1,chr)));
}
// 删除字符串中的指定字符, 返回字符串
static char *trimString(char *str, char chr)
{
#pragma warning( disable: 4996 )
return lstrcpy(str, trim(str, chr));
#pragma warning( default: 4996 )
}
// 提取X509证书序列号,返回与IE看到的证书序列一致(去掉空格)
static BOOL parseX509CertSerialNumber(PCCERT_CONTEXT hCert, char sn[])
{
int i, len;
char c0, c1;
BOOL bResult;
CRYPT_INTEGER_BLOB SerialNumber;
char *s;
// 取得要解码的信息尺寸
bResult = CryptFormatObject(
hCert->dwCertEncodingType,
0,
0,
NULL,
0,
hCert->pCertInfo->SerialNumber.pbData,
hCert->pCertInfo->SerialNumber.cbData,
NULL,
&SerialNumber.cbData);
ASSERT(bResult);
if (!bResult)
return FALSE;
// 分配解码数据存放
SerialNumber.pbData = (BYTE *) malloc(SerialNumber.cbData);
// 解码数据
bResult = CryptFormatObject(
hCert->dwCertEncodingType,
0,
0,
NULL,
0,
hCert->pCertInfo->SerialNumber.pbData,
hCert->pCertInfo->SerialNumber.cbData,
SerialNumber.pbData ,
&SerialNumber.cbData);
ASSERT(bResult);
if (!bResult){
free(SerialNumber.pbData);
return FALSE;
}
s = (char*) malloc(48);
s = ::_com_util::ConvertBSTRToString((BSTR)SerialNumber.pbData);
lstrcpy(sn, s);
free(s);
free(SerialNumber.pbData);
// 去除空格
trimString(sn, 32);
// 颠倒字符串
len = strlen(sn);
ASSERT(len%2==0);
for(i=0; i<len/2; i+=2){
c0 = sn[i];
c1 = sn[i+1];
sn[i]=sn[len-i-2];
sn[i+1]=sn[len-i-1];
sn[len-i-2]=c0;
sn[len-i-1]=c1;
}
return TRUE;
}
==========================
如下代码调用:
------------------------------------------------------------------------------------------------------------
HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
PKCS_7_ASN_ENCODING|X509_ASN_ENCODING,
0,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if (hStore==NULL){
throw "Fail to open my cert store";
}
// 要查找的证书
char szBuf[512];
szBuf[511]=0;
BOOL bRet;
DWORD cbSize;
PCCERT_CONTEXT hCert = 0;
char SerialNumber[48]; // 必须是48
while((hCert=CertEnumCertificatesInStore(hStore, hCert)) != NULL){
// 发行者名称
cbSize = CertGetNameString(hCert,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG,
0,
szBuf,
128);
// 取出序列号
if (!parseX509CertSerialNumber(hCert, SerialNumber)){
bRet = CertCloseStore(hStore, 0);
throw "Fail to get serial number";
}
// SerialNumber存放了你想要的序列号,如:
// "df48a548cef576bb4ae7a726b6938424"
// 做你喜欢的事
......
}
// 关掉这个家伙
bRet = CertCloseStore(hStore, 0);
-----------------------------------------------------------------------------------------------
通过Win32 CryptAPI查找个人证书库(MY)中的指定的证书的序列号。显示之。证书的序列号经过处理,和IE中显示的一样(只是人为地去掉了空格)。
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")
头文件
view plainprint?
// 去除指定字符
// 下面的代码用于字符串替换
static char* trim(char *str, char chr){
return (*str==0)?str:(((*str!=chr)?(((trim(str+1, chr)-1)==str)?str:(*(trim(str+1,chr)-1)=*str,*str=chr,trim(str+1,chr))):trim(str+1,chr)));
}
// 删除字符串中的指定字符, 返回字符串
static char *trimString(char *str, char chr)
{
#pragma warning( disable: 4996 )
return lstrcpy(str, trim(str, chr));
#pragma warning( default: 4996 )
}
// 提取X509证书序列号,返回与IE看到的证书序列一致(去掉空格)
static BOOL parseX509CertSerialNumber(PCCERT_CONTEXT hCert, char sn[])
{
int i, len;
char c0, c1;
BOOL bResult;
CRYPT_INTEGER_BLOB SerialNumber;
char *s;
// 取得要解码的信息尺寸
bResult = CryptFormatObject(
hCert->dwCertEncodingType,
0,
0,
NULL,
0,
hCert->pCertInfo->SerialNumber.pbData,
hCert->pCertInfo->SerialNumber.cbData,
NULL,
&SerialNumber.cbData);
ASSERT(bResult);
if (!bResult)
return FALSE;
// 分配解码数据存放
SerialNumber.pbData = (BYTE *) malloc(SerialNumber.cbData);
// 解码数据
bResult = CryptFormatObject(
hCert->dwCertEncodingType,
0,
0,
NULL,
0,
hCert->pCertInfo->SerialNumber.pbData,
hCert->pCertInfo->SerialNumber.cbData,
SerialNumber.pbData ,
&SerialNumber.cbData);
ASSERT(bResult);
if (!bResult){
free(SerialNumber.pbData);
return FALSE;
}
s = (char*) malloc(48);
s = ::_com_util::ConvertBSTRToString((BSTR)SerialNumber.pbData);
lstrcpy(sn, s);
free(s);
free(SerialNumber.pbData);
// 去除空格
trimString(sn, 32);
// 颠倒字符串
len = strlen(sn);
ASSERT(len%2==0);
for(i=0; i<len/2; i+=2){
c0 = sn[i];
c1 = sn[i+1];
sn[i]=sn[len-i-2];
sn[i+1]=sn[len-i-1];
sn[len-i-2]=c0;
sn[len-i-1]=c1;
}
return TRUE;
}
==========================
如下代码调用:
------------------------------------------------------------------------------------------------------------
HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
PKCS_7_ASN_ENCODING|X509_ASN_ENCODING,
0,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if (hStore==NULL){
throw "Fail to open my cert store";
}
// 要查找的证书
char szBuf[512];
szBuf[511]=0;
BOOL bRet;
DWORD cbSize;
PCCERT_CONTEXT hCert = 0;
char SerialNumber[48]; // 必须是48
while((hCert=CertEnumCertificatesInStore(hStore, hCert)) != NULL){
// 发行者名称
cbSize = CertGetNameString(hCert,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG,
0,
szBuf,
128);
// 取出序列号
if (!parseX509CertSerialNumber(hCert, SerialNumber)){
bRet = CertCloseStore(hStore, 0);
throw "Fail to get serial number";
}
// SerialNumber存放了你想要的序列号,如:
// "df48a548cef576bb4ae7a726b6938424"
// 做你喜欢的事
......
}
// 关掉这个家伙
bRet = CertCloseStore(hStore, 0);
-----------------------------------------------------------------------------------------------
相关文章推荐
- 一段 CryptAPI 取得 证书序列号 的代码
- 一段 CryptAPI 取得 证书序列号 的代码
- openssl 证书操作命令
- Webstorm & PhpStorm的序列号和证书
- Linq查询数据集取得排序后的序列号(行号)
- 取得前一次MySQL操作所影响的记录行数
- OpenSSL 常用证书操作函数
- C#获取cpu序列号 硬盘ID 网卡硬地址以及操作注册表
- C语言操作WINDOWS系统存储区数字证书相关函数详解及实例
- Webstorm & PhpStorm的序列号和证书
- Python常用时间操作总结【取得当前时间、时间函数、应用等】
- JKS证书库操作记录
- 使用keytool对证书进行操作
- jquery取得text,areatext,radio,checkbox,select的值,以及其他一些操作
- 拆分pkcs12证书常用的操作
- 证书导入和导出操作支持四种文件格式
- C语言操作WINDOWS系统存储区数字证书相关函数详解及实例
- JAVA对数字证书的常用操作
- java如何操作字符串取得绝对路径中的文件名及文件夹名
- Windows 2003,ASP,使用Request.ClientCertificate("Certificate")取得的证书全文不正确