Featured post
c++ - MS Crypto API behavior on Windows XP vs Vista/7 -
i'm trying understand how public key imported pem format (sample included in code below) across xp, vista , windows 7. sample code import key on both xp , windows vista/7, not same way.
on windows xp, string "(prototype)" required in cryptographic provider's name, , allows call cryptimportpublickeyinfo pass.
on windows 7, "(prototype)" provider apparently present, not support call cryptimportpublickeyinfo, confusing.
what might correct implementation between these operating systems? necessary detect xp , request name "(prototype)", , without other operating systems? possible that still fail on xp systems?
or, there way detect confusing behavior , select whichever cryptographic provider support necessary call?
output on windows 7:
analyzing cryptographic support for: "microsoft enhanced rsa , aes cryptographic provider" cryptacquirecontext success. cryptacquirecontext.1 success. cryptstringtobinary.2 success. cryptdecodeobjectex success. cryptimportpublickeyinfo success. success. analyzing cryptographic support for: "microsoft enhanced rsa , aes cryptographic provider (prototype)" cryptacquirecontext success. cryptacquirecontext.1 success. cryptstringtobinary.2 success. cryptdecodeobjectex success. cryptimportpublickeyinfo failed****.
output on windows xp:
analyzing cryptographic support for: "microsoft enhanced rsa , aes cryptographic provider" cryptacquirecontext success. cryptacquirecontext.1 success. cryptstringtobinary.2 success. cryptdecodeobjectex success. cryptimportpublickeyinfo failed****. analyzing cryptographic support for: "microsoft enhanced rsa , aes cryptographic provider (prototype)" cryptacquirecontext success. cryptacquirecontext.1 success. cryptstringtobinary.2 success. cryptdecodeobjectex success. cryptimportpublickeyinfo success. success.
c++ source code produces output: (requires crypt32.lib)
#include <stdio.h> #include <tchar.h> #include <windows.h> #include <wincrypt.h> bool windowsacquireprovidercontext(hcryptprov *phandleprov, lpctstr pprovidername); bool analyzecryptographicsupport(lpctstr pprovidername); int _tmain(int argc, _tchar* argv[]) { analyzecryptographicsupport(ms_enh_rsa_aes_prov); analyzecryptographicsupport(l"microsoft enhanced rsa , aes cryptographic provider (prototype)"); return 0; } bool windowsacquireprovidercontext(hcryptprov *phandleprov, lpctstr pprovidername) { wchar *pcontainername = l"blah blah blah"; if(!cryptacquirecontext(phandleprov, pcontainername, pprovidername, prov_rsa_aes, crypt_silent)) { if(getlasterror() == nte_bad_keyset) { if(cryptacquirecontext(phandleprov, pcontainername, pprovidername, prov_rsa_aes, crypt_newkeyset|crypt_silent)) { return true; } } } return true; } lpcwstr pwszpempublickey = l"-----begin public key-----\r\n" l"migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqc6guvcbn92bahlwoskki8xkg9q\r\n" l"vq863+c4cowc6hzjojc011pjffibu8/pg1ei8fzjdbmtrfajtriyw1/spboh0qqe\r\n" l"ehant8qwn+s5m9xgdjowtbjkcnu3ohovjju3c8johqqnrwlfghjh4vnwstdiwuuy\r\n" l"smwpwuhobsnelgbgeqidaqab\r\n" l"-----end public key-----\r\n"; int pempublickeysize = wcslen(pwszpempublickey); bool analyzecryptographicsupport(lpctstr pprovidername) { printf("analyzing cryptographic support for:\r\n"); wprintf(l"\t \"%s\"\r\n", pprovidername); hcryptprov hprov; if(!windowsacquireprovidercontext(&hprov, pprovidername)) { wprintf(l"\t cryptacquirecontext failed.\r\n"); return false; } wprintf(l"\t cryptacquirecontext success.\r\n"); dword blobsize; if(!cryptstringtobinary(pwszpempublickey, pempublickeysize, crypt_string_base64_any, null, &blobsize, null, null)) { cryptreleasecontext(hprov, 0); wprintf(l"\t cryptstringtobinary.1 failed****.\r\n"); return false; } wprintf(l"\t cryptacquirecontext.1 success.\r\n"); byte *pblob = (byte *)malloc(blobsize); if(!cryptstringtobinary(pwszpempublickey, pempublickeysize, crypt_string_base64_any, pblob, &blobsize, null, null)) { free(pblob); cryptreleasecontext(hprov, 0); wprintf(l"\t cryptstringtobinary.2 failed****.\r\n"); return false; } wprintf(l"\t cryptstringtobinary.2 success.\r\n"); cert_public_key_info *publickeyinfo; dword publickeyinfolen; hcryptkey hpublickey; if(!cryptdecodeobjectex(x509_asn_encoding|pkcs_7_asn_encoding, x509_public_key_info, pblob, blobsize, crypt_decode_alloc_flag, null, &publickeyinfo, &publickeyinfolen)) { free(pblob); cryptreleasecontext(hprov, 0); wprintf(l"\t cryptdecodeobjectex failed****.\r\n"); return false; } wprintf(l"\t cryptdecodeobjectex success.\r\n"); if(!cryptimportpublickeyinfo(hprov, x509_asn_encoding|pkcs_7_asn_encoding, publickeyinfo, &hpublickey)) { localfree(publickeyinfo); free(pblob); cryptreleasecontext(hprov, 0); wprintf(l"\t cryptimportpublickeyinfo failed****.\r\n"); return false; } wprintf(l"\t cryptimportpublickeyinfo success.\r\n"); cryptdestroykey(hpublickey); localfree(publickeyinfo); free(pblob); cryptreleasecontext(hprov, 0); wprintf(l"\t success.\r\n"); return true; }
the reason of problem describes easy: microsoft renamed aes cryptographic provider
"microsoft enhanced rsa , aes cryptographic provider (prototype)"
in windows xp"microsoft enhanced rsa , aes cryptographic provider"
in later versions of operation systems.
in wincrypt.h
defined corresponding constants ms_enh_rsa_aes_prov
, ms_enh_rsa_aes_prov_xp
can use.
if don't want test version of operation system can use cryptacquirecontext null
pszprovider
(and continue use prov_rsa_aes
dwprovtype
). in code can include analyzecryptographicsupport(null);
.
you can examine "name" value of registry key
hkey_local_machine\software\microsoft\cryptography\defaults\provider types\type 024
to see name of default prov_rsa_aes
provider.
- Get link
- X
- Other Apps
Comments
Post a Comment