我在this question中读到了有关从本机组件导入公钥的信息。 我尝试基于BLOB文档对私钥做同样的事情,但是我收到了NTE_BAD_DATA错误。
我的想法可行吗?如果是的话,你能帮忙吗?
我的尝试:
void old_RSA_decrypt(PBYTE blob, DWORD blobSize)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
DWORD dwDecryptedLen = 0;
DWORD length;
std::ifstream f;
f.open("c:\\Programming\\encrypted.txt", std::ios::binary);
if (!f.is_open())
{
std::cout << "Error on open file: " << GetLastError() << std::endl;
return;
}
f.seekg(0, f.end);
length = f.tellg();
f.seekg(0, f.beg);
char * buffer = new char[length];
f.read(buffer, length);
if (!f)
std::cout << "error: only " << f.gcount() << " could be read" << std::endl;
f.close();
PBYTE bBuffer = (PBYTE)buffer;
//now to get the decryption thing going
if (!CryptAcquireContext(
&hCryptProv,
NULL,
MS_STRONG_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
std::cout << "Error on CryptAcquireContext " << GetLastError() << std::endl;
return;
}
if (!CryptImportKey(
hCryptProv,
blob,
blobSize,
NULL,
0,
&hKey))
{
std::cout << "Error on CryptImportKey " << GetLastError() << std::endl;
return;
}
if (!CryptDecrypt(hKey, NULL, TRUE, 0, NULL, &dwDecryptedLen))
{
std::cout << "Error on CryptDecrypt (First Pass) " << GetLastError() << std::endl;
return;
}
PBYTE decBuffer = new BYTE[dwDecryptedLen];
for(int i = 0; i < length ; ++i)
decBuffer[i] = bBuffer[i];
if (!CryptDecrypt(hKey, NULL, TRUE, 0, decBuffer, &length))
{
std::cout << "Error on CryptDecrypt (Second Pass) " << GetLastError() << std::endl;
return;
}
std::cout << "Yurika2!" << std::endl;
std::ofstream of;
of.open("c:\\Programming\\decrypted.txt", std::ios::binary);
if (!of.is_open())
{
std::cout << "Error on open write file: " << GetLastError() << std::endl;
return;
}
string sDecMsg = string(reinterpret_cast<char*>(decBuffer), length);
of << sDecMsg << std::endl;
of.close();
cleanup:
delete[] buffer;
delete[] decBuffer;
}
void do_decrypt()
{
string modStr = "yVUndgQFuB5Z5FgC0/WgWCg6Y8VuB582avGjQDdeoJDa1+RBKCyXo700sAMSGjM/bVakOlFqvCsVFNBysx1CH731CDb2DR1a0bsmYmDQ9d0ZHX+AOohVDIx9mc7bkDQZoEFpe9NqFsu95Y9yktpl1JKPmKyLOFgufGJYYvQyoOM=";
string expStr = "AQAB";
string PStr = "/JydNn89lSWjgWOG1XRJm1qTWDekzzoLfTQU+GK+h8DGQ6gkUbgqGosLGo+eAxbO/ETZV3ibbBuIdvL4UxC5Qw==";
string QStr = "zAh23Gc8Oqz/Uh2wh+yt8DqUesVLwMn2koc9CbyF9/Z5Qe8OIR4yygJtuYruRC1x/KYj85l6DGzstUZOtYmv4Q==";
string DPStr ="+1INj1SUPjjOLUKJuQAS4z7/7PqfO5RyLcSNQHltOb5vAozcZXkmWnYPPAO6nzQoBg+xdDcH2kyiPkWJDYtL5Q==";
string DQStr = "cbYh8HJEufrijTRox0hcJG+xgr7kmjy1BDMFDKEaFPkz2VBPEpwO+FDkMC1C35JoXcOGc+RMhhJK1jip8zkaYQ==";
string InverseQStr = "3PAXzlAXgvLVrbOEygjA2zhJEYALBEi6VTKqfDKlnv8/D9QUkC39bEDIRLG0wMFFxN8NlLx5zTiiVswxnMy8Mw==";
string DStr = "KKBSyKkyID+bowyxcWUAuJlRgv19YPNbL0RYTWZ+5UalqmfoT/uDk+pjndrYxcmulFkl5ZC1SYgmBl+zrXoLc/Ei86BtNiuwfcqHlUDp0fdP+fyYN45wh/251HQ3UM1zBpMP8XeYB6zjpCU/s3/wCBE6WpJWN9fKcG0W5PLq8eE=";
//FROM STRINGS TO BYTE VECTORS!
vector<BYTE> modBinMSB = base64_decode(modStr);
vector<BYTE> expBinMSB = base64_decode(expStr);
vector<BYTE> PBinMSB = base64_decode(PStr);
vector<BYTE> QBinMSB = base64_decode(QStr);
vector<BYTE> DPBinMSB = base64_decode(DPStr);
vector<BYTE> DQBinMSB = base64_decode(DQStr);
vector<BYTE> InverseQBinMSB = base64_decode(InverseQStr);
vector<BYTE> DBinMSB = base64_decode(DStr);
//TURN MSB TO LSB
DWORD offset = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY); // to keep track of things
const DWORD modulusLengthInBytes = 128;
DWORD keyBlobLength = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + (modulusLengthInBytes * 4) + (modulusLengthInBytes / 2);
BYTE* keyBlob = (PBYTE)malloc(keyBlobLength);
BLOBHEADER* blobheader = (BLOBHEADER*)keyBlob;
blobheader->bType = PRIVATEKEYBLOB;
blobheader->bVersion = CUR_BLOB_VERSION;
blobheader->reserved = 0;
blobheader->aiKeyAlg = CALG_RSA_KEYX;
RSAPUBKEY* rsapubkey = (RSAPUBKEY*)(keyBlob + sizeof(BLOBHEADER));
rsapubkey->magic = 0x31415352;
rsapubkey->bitlen = modulusLengthInBytes * 8 *4 + modulusLengthInBytes*4;
rsapubkey->pubexp = MSBByteVectorToDword(expBinMSB);
BYTE* modulus = keyBlob + offset;
copyReversed(modBinMSB, modulus);
offset += modulusLengthInBytes;
BYTE* prime1 = keyBlob + offset ;
copyReversed(PBinMSB, prime1);
offset += modulusLengthInBytes / 2;
BYTE* prime2 = keyBlob + offset;
copyReversed(QBinMSB, prime2);
offset += (modulusLengthInBytes / 2);
BYTE* exponent1 = keyBlob + offset;
copyReversed(DPBinMSB, exponent1);
offset += (modulusLengthInBytes / 2);
BYTE* exponent2 = keyBlob + offset;
copyReversed(DQBinMSB, exponent2);
offset += (modulusLengthInBytes / 2);
BYTE* coefficient = keyBlob + offset;
copyReversed(InverseQBinMSB, coefficient);
offset += modulusLengthInBytes / 2;
BYTE* privateExponent = keyBlob + offset;
copyReversed(DBinMSB, privateExponent);
old_RSA_decrypt(keyBlob, keyBlobLength);
}
答案 0 :(得分:0)
当然可以这样做。您提到了两个Windows加密堆栈,但存在一些差异:
我在你的代码中看到一个明显的错误:
rsapubkey->bitlen = modulusLengthInBytes * 8 *4 + modulusLengthInBytes*4;
<强> bitlen 强>
模数中的位数。在实践中,这必须始终是8的倍数。
所以只是
rsapubkey->bitlen = modulusLengthInBytes * 8;
您对dwMagic值的设置似乎也不正确。
rsapubkey->magic = 0x31415352;
0x31415352是RSA_PUB_MAGIC,因此您将自己称为公钥。你想要RSA_PRIV_MAGIC(并使用常量)。
rsapubkey->magic = RSA_PRIV_MAGIC;
与http://source.dot.net/#System.Security.Cryptography.Csp/System/Security/Cryptography/CapiHelper.Shared.cs,b7bc764e6deb34f5比较,这是C#中一个有效的blob编写器。