The original is in http://bbs.pediy.com/archive/index.php?t-97663.html, but I think this article is very good, I copied down to make my notes with
I. Analysis of X509 certificate
1. Read the certificate data from the certificate file on disk
unsigned char* pbx509data; Certificate data
unsigned long Ulx509datalen; Certificate Data length
2. Get Certcontext
Pccert_context Pcertcontext = CertCreateCertificateContext (x509_asn_encoding, Pbx509data, UlX509DataLen);
3. Obtaining Certificate Information
pcertcontext->pcertinfo->dwversion; Certificate version number
Crypt_integer_blob Snblob = pcertcontext->pcertinfo->serialnumber; Certificate SN
Cert_name_blob Issuerblob = pcertcontext->pcertinfo->issuer; Certificate issuer
Cert_name_blob Subjectblob = pcertcontext->pcertinfo->subject; Certificate subject
Certificate Valid Starting Date
SYSTEMTIME SysTime;
memset (&systime, 0, sizeof (sysTime));
FileTimeToSystemTime (&pcertcontext->pcertinfo->notbefore, &systime);
Char sztime[128] = {0};
sprintf_s (Sztime, +, "%d%d months%d days%d:%d:%d", Systime.wyear, Systime.wmonth, Systime.wday, Systime.whour, Systime.wminute, Systime.wsecond);
Certificate Valid Expiration date
memset (&systime, 0, sizeof (sysTime));
FileTimeToSystemTime (&pcertcontext->pcertinfo->notafter, &systime);
memset (sztime, 0, sizeof (sztime));
sprintf_s (Sztime, +, "%d%d months%d days%d:%d:%d", Systime.wyear, Systime.wmonth, Systime.wday, Systime.whour, Systime.wminute, Systime.wsecond);
4. Create a temporary key container
Hcryptprov Htmpprov = NULL;
if (rcrypt_failed (CryptAcquireContext (&htmpprov, "My_temporary_container", NULL, Prov_rsa_aes, CRYPT_NEWKEYSET) ))//null means using the system default CSP
{
if (rcrypt_failed (CryptAcquireContext (&htmpprov, "My_temporary_container", NULL, Prov_rsa_aes, 0))// Null means using the system default CSP
{
Certfreecertificatecontext (Pcertcontext);
return nte_fail;
}
}
5. Import the public key into the container to get the public key handle
Hcryptkey HKey = NULL;
Cert_public_key_info Certpubkeyinfo = pcertcontext->pcertinfo->subjectpublickeyinfo;
Cryptimportpublickeyinfo (Htmpprov, x509_asn_encoding| Pkcs_7_asn_encoding, &certpubkeyinfo, &hkey);
6. Export the public key (preferably with two call methods)
unsigned char* pBuf = NULL;
unsigned long ulbuflen = 0;
CryptExportKey (HKey, 0, PublicKeyBlob, 0, PBuf, &ulbuflen);
PBuf = new unsigned char[ulbuflen];
memset (pBuf, 0, Ulbuflen);
CryptExportKey (HKey, 0, PublicKeyBlob, 0, PBuf, &ulbuflen);
7. Get Public key information
unsigned char* p = pBuf + sizeof (PUBLICKEYSTRUC);
(* (rsapubkey*) p). Bitlen; Public key modulo length (in bits)
(* (rsapubkey*) p). Pubexp; E of the public key (note byte order)
p + = sizeof (Rsapubkey); N of public key (note byte order)
8. Cleanup work
Delete[] PBuf;
PBuf = NULL;
Cryptdestroykey (HKey);
CryptReleaseContext (Htmpprov, 0);
Certfreecertificatecontext (Pcertcontext);
Second, analytic P12 certificate
1. Read the certificate data from the certificate file on disk
unsigned char* pbp12data; Certificate data
unsigned long Ulp12datalen; Certificate Data length
2. Let the user enter the certificate password
char* szpwd; Certificate Password
3. Convert the certificate password into Unicode format (preferably with two calls)
LPWSTR Pwidechar = NULL;
int Nwidechar = 0;
Nwidechar = MultiByteToWideChar (CP_ACP, 0, Szpwd,-1, Pwidechar, Nwidechar);
Pwidechar = new Wchar[nwidechar];
memset (Pwidechar, 0, sizeof (WCHAR) *nwidechar);
MultiByteToWideChar (CP_ACP, 0, Szpwd,-1, Pwidechar, Nwidechar);
4. Import the certificate data into the temporary store
Crypt_data_blob BLOB;
memset (&blob, 0, sizeof (BLOB));
Blob.pbdata = Pbp12data;
Blob.cbdata = Ulp12datalen;
Hcertstore Hcertstore = NULL;
Hcertstore = Pfximportcertstore (&blob, Pwidechar, crypt_exportable);
5. Find the certificate in the store and get Certcontext
Pccert_context Pcertcontext = CertFindCertificateInStore (Hcertstore, x509_asn_encoding| pkcs_7_asn_encoding, 0, cert_find_any, NULL, or NULL);
6. Obtaining Certificate information
Crypt_integer_blob Snblob = pcertcontext->pcertinfo->serialnumber; Certificate SN
pcertcontext->pbcertencoded; X509 Format certificate Data
pcertcontext->cbcertencoded; X509 Format Certificate Data length
7. Get the CSP handle
Hcryptprov Hprov = NULL;
DWORD dwkeyspec = 0;
BOOL Bcallerfreeprov = FALSE;
Cryptacquirecertificateprivatekey (pcertcontext, 0, NULL, &hprov, &dwkeyspec, &bcallerfreeprov);
8. Get the key handle
Hcryptkey HKey = NULL;
Cryptgetuserkey (Hprov, Dwkeyspec, &hkey);
9. Export the private key (preferably with two call methods)
byte* pbdata = NULL;
DWORD Dwdatalen = 0;
CryptExportKey (HKey, NULL, Privatekeyblob, 0, pbdata, &dwdatalen);
Pbdata = new Byte[dwdatalen];
memset (pbdata, 0, Dwdatalen);
CryptExportKey (HKey, NULL, Privatekeyblob, 0, pbdata, &dwdatalen);
10. Get Public Private key information
BYTE *p = pbdata+ sizeof (PUBLICKEYSTRUC);
(* (rsapubkey*) p). Bitlen; Public key modulus (in bits)
(* (rsapubkey*) p). Pubexp; E of the public key (note byte order)
p + = sizeof (Rsapubkey); N of Public private key (note byte order)
p + = ((* (rsapubkey*) p). Bitlen)/8; P (note byte order) of the private key
p + = ((* (rsapubkey*) p). Bitlen)/16; Q of the private key (note byte order)
p + = ((* (rsapubkey*) p). Bitlen)/16; DP of the private key (note byte order)
p + = ((* (rsapubkey*) p). Bitlen)/16; DQ of the private key (note byte order)
p + = ((* (rsapubkey*) p). Bitlen)/16; Qu of the private key (note byte order)
p + = ((* (rsapubkey*) p). Bitlen)/16; D of the private key (note byte order)
11. Cleanup work
Delete[] pbdata;
Pbdata = NULL;
Cryptdestroykey (HKey);
CryptReleaseContext (Hprov, 0);
Certfreecertificatecontext (Pcertcontext);
CertCloseStore (Hcertstore, Cert_close_store_force_flag);
Delete[] Pwidechar;
Pwidechar = NULL;
Note: In order to shorten the space, the above code does not contain errors and exception handling.
[repost] use CryptoAPI to resolve X509 certificate and P12 certificate