使用Microsoft CryptoAPI,我已經生成了一個新的RSA密鑰對,並且現在正試圖將私鑰導出到PKCS#8加密(受密碼保護)的PEM文件。如何使用MS CryptoAPI導出受密碼保護的私鑰?
我首先研究了CryptExportPKCS8()和CryptExportPKCS8Ex(),但前者不支持加密密鑰,後者是not exported by crypt32.dll。 MSDN說這兩個函數都被棄用了。
我現在的嘗試是通過從密碼到CryptExportKey(衍生)會話密鑰:()
HCRYPTPROV provider;
BOOL result = CryptAcquireContext(&provider, CONTAINER_NAME, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT);
HCRYPTKEY keyPair;
result = CryptGenKey(provider, CALG_RSA_KEYX, (2048 << 16) | CRYPT_EXPORTABLE, &keyPair);
HCRYPTHASH hash;
result = CryptCreateHash(provider, CALG_SHA1, 0, 0, &hash);
const char *password = "password";
result = CryptHashData(hash, (const BYTE *)password, strlen(password), 0);
HCRYPTKEY sessionKey;
result = CryptDeriveKey(provider, CALG_3DES, hash, CRYPT_EXPORTABLE, &sessionKey);
DWORD blobSize;
result = CryptExportKey(keyPair, sessionKey, PRIVATEKEYBLOB, 0, NULL, &blobSize);
BYTE *blobBytes = new BYTE[blobSize];
result = CryptExportKey(keyPair, sessionKey, PRIVATEKEYBLOB, 0, blobBytes, &blobSize);
DWORD derSize;
// This throws "First-chance exception ... Access violation reading ..." and returns FALSE
result = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, blobBytes, 0, NULL, NULL, &derSize);
// error is 3221225477 (0xC0000005)
DWORD error = GetLastError();
BYTE *derBytes = new BYTE[derSize];
result = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, blobBytes, 0, NULL, derBytes, &derSize);
// ... CryptBinaryToString() to convert to PEM
// ... Write PEM to file
所有呼叫成功,直到評論CryptEncodeObjectEx。
如果我沒有將會話密鑰傳遞給CryptExportKey(),那麼我可以成功地使用CryptEncodeObjectEx()來對私鑰進行編碼,但顯然它是純文本的。
如何導出受密碼保護的私鑰?我推導會話密鑰的方式有什麼問題嗎? PKCS_RSA_PRIVATE_KEY是錯誤的編碼類型嗎?
我已經在Visual Studio 2013在Windows 7
pvEncoded是什麼格式? 'openssl asn1parse -inform DER -in test.der'顯示有效的ASN.1,但'openssl pkcs8 -inform DER -in test.der'給出'未知的pbe算法:evp_pbe.c:162:TYPE = des-ede3-cbc '。 –