經過CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, NULL, &dwBlobLen)算法
1 #include <Windows.h> 2 #include <WinCrypt.h> 3 #include <stdio.h> 4 #include <tchar.h> 5 6 #pragma comment(lib, "crypt32.lib") 7 8 #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING|X509_ASN_ENCODING) 9 10 void HandleError(char * str) 11 { 12 printf("%s[%x]\n",str,GetLastError()); 13 system("pause"); 14 exit(1); 15 } 16 17 int main(int argc, char* argv[]) 18 { 19 HCRYPTPROV hCryptProv = NULL; //CSP句柄 20 LPCTSTR pszContainerName = TEXT("MyKeyContainer"); //CSP密鑰容器句柄 21 HCRYPTKEY hKey = NULL; 22 BYTE* pbKeyBlob; 23 DWORD dwBlobLen; 24 25 if(CryptAcquireContext( 26 &hCryptProv, 27 NULL, 28 NULL, 29 PROV_RSA_FULL, 30 0)) 31 { 32 printf("獲取到"); 33 _tprintf(TEXT("[%s]"), pszContainerName); 34 printf("的密鑰容器\n"); 35 } 36 else 37 { 38 //發生錯誤,若是是密鑰容器不存在,則建立新的密鑰容器 39 if (GetLastError() == NTE_BAD_KEYSET) 40 { 41 if (CryptAcquireContext( 42 &hCryptProv, 43 NULL, 44 NULL, 45 PROV_RSA_FULL, 46 CRYPT_NEWKEYSET)) 47 { 48 printf("新的密鑰容器已建立\n"); 49 } 50 else 51 { 52 HandleError("沒法建立密鑰容器"); 53 } 54 } 55 else 56 { 57 HandleError("沒法獲取CSP句柄"); 58 } 59 } 60 61 62 //獲取一個加解密key句柄 63 if (CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hKey)) 64 { 65 printf("獲取到加解密key句柄\n"); 66 } 67 else 68 { 69 if (GetLastError() == NTE_NO_KEY) 70 { 71 //由於沒有密鑰對, 建立一個 72 printf("密鑰對不存在,建立一個密鑰對\n"); 73 if (CryptGenKey(hCryptProv, AT_KEYEXCHANGE,CRYPT_EXPORTABLE,&hKey)) 74 { 75 printf("建立簽名驗籤密鑰對成功\n"); 76 } 77 else 78 { 79 HandleError("建立密鑰對失敗"); 80 } 81 } 82 else 83 { 84 HandleError("獲取密鑰對錯誤,簽名驗籤密鑰對不可用"); 85 } 86 } 87 88 //PUBLICKEYBLOB 89 //PRIVATEKEYBLOB 90 if(!(CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, NULL, &dwBlobLen))) 91 { 92 HandleError("導出公鑰信息失敗"); 93 } 94 95 pbKeyBlob = (BYTE*)malloc(dwBlobLen); 96 97 if(!(CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, pbKeyBlob, &dwBlobLen))) 98 { 99 HandleError("導出公鑰信息失敗2;"); 100 } 101 102 103 printf("公鑰BLOB信息以下:\n"); 104 for(int i=0;i<dwBlobLen;i++) 105 { 106 if (i % 10 == 0) 107 { 108 printf("\n"); 109 } 110 printf("%02X ", pbKeyBlob[i]); 111 } 112 printf("\n"); 113 114 BLOBHEADER blobHeader; 115 RSAPUBKEY rsaPubkey; 116 PBYTE p = NULL; 117 p = pbKeyBlob; 118 //分析獲得的BLOB 119 memcpy(&blobHeader.bType, p, 1); 120 p += 1; 121 memcpy(&blobHeader.bVersion, p, 1); 122 p += 1; 123 memcpy(&blobHeader.reserved, p, 2); 124 p += 2; 125 memcpy(&blobHeader.aiKeyAlg, p, 4); 126 p += 4; 127 128 memcpy(&rsaPubkey.magic, p, 4); 129 p += 4; 130 memcpy(&rsaPubkey.bitlen, p, 4); 131 p += 4; 132 memcpy(&rsaPubkey.pubexp, p, 4); 133 p += 4; 134 PBYTE reaMod = (PBYTE)LocalAlloc(LPTR, rsaPubkey.bitlen/8); 135 memcpy(reaMod, p, rsaPubkey.bitlen/8); 136 137 //須要轉換一下 138 BYTE bTemp; 139 for (int i=0;i< rsaPubkey.bitlen/8/2; i++) 140 { 141 bTemp = reaMod[i]; 142 reaMod[i] = reaMod[rsaPubkey.bitlen/8 - i - 1]; 143 reaMod[rsaPubkey.bitlen/8- i - 1] = bTemp; 144 } 145 146 printf("BLOBHEADER.bType=[%02x]\n", blobHeader.bType); 147 printf("BLOBHEADER.bVersion=[%02x]\n", blobHeader.bVersion); 148 printf("BLOBHEADER.reserved=[%d]\n", blobHeader.reserved); 149 printf("BLOBHEADER.aiKeyAlg=[%d]\n\n", blobHeader.aiKeyAlg); 150 printf("rsaPubkey.magic=["); 151 char* q = (char *)&rsaPubkey.magic; 152 for (int i = 0;i<4;i++) 153 { 154 printf("%c",*q++); 155 } 156 157 printf("]\nrsaPubkey.bitlen=[%d]\n", rsaPubkey.bitlen); 158 printf("rsaPubkey.pubexp=[%d]\n", rsaPubkey.pubexp); 159 printf("RSA MOD:\n"); 160 for(int i=0;i<rsaPubkey.bitlen/8;i++) 161 { 162 if (i % 10 == 0) 163 { 164 printf("\n"); 165 } 166 printf("%02X ", reaMod[i]); 167 } 168 printf("\n"); 169 170 //釋放 171 LocalFree(reaMod); 172 173 174 free(pbKeyBlob); 175 if (hKey) 176 { 177 CryptDestroyKey(hKey); 178 } 179 180 if(hCryptProv) 181 { 182 CryptReleaseContext(hCryptProv, 0); 183 } 184 185 if(CryptAcquireContext( 186 &hCryptProv, 187 NULL, 188 NULL, 189 PROV_RSA_FULL, 190 CRYPT_DELETEKEYSET)) 191 { 192 printf("刪除容器成功\n"); 193 } 194 else 195 { 196 HandleError("刪除容器失敗"); 197 } 198 system("pause"); 199 return 0; 200 }
結果以下:函數
導出私鑰的代碼跟導出公鑰相似,修改CryptExportKey函數的第3個參數爲PRIVATEKEYBLOB 便可。ui