经过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