2017-06-01 26 views
0

私はthis questionを読んでいます。ネイティブコンポーネントから公開鍵をインポートしています。 私はBLOBのドキュメントに基づいて秘密鍵についても同じことを試みましたが、NTE_BAD_DATAエラーが発生しました。C++ xmlからCAPI/CNGのRSA秘密鍵をインポートします

私の考えは実現可能ですか?もしそうなら、助けてもらえますか?

マイ試してみてください。

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

それはそうすることを確実に可能です。あなたがWindowsの暗号スタックの両方に言及し、いくつかの違いがあります。

  • エンコード:
    • CAPI:可変長フィールドの全ては、リトルエンディアンです。
    • CNG:すべての可変長フィールドがビッグエンディアンです。
  • 剛性:
    • CAPI:モジュラス及びDは同じ長さを有していなければなりません。また、P、Q、DP、DQ、InverseQはすべて同じ長さ(モジュラスの長さの半分(丸め)でなければならない)を有する。
    • CNG:秘密鍵はn、e、p、およびq ...のみを要求し、各フィールドの長さを個別に指定します。

      rsapubkey->bitlen = modulusLengthInBytes * 8 *4 + modulusLengthInBytes*4; 
      

      the documentationパー:モジュラスのビット

      bitlen

は、私はあなたのコード内の1つの明白なエラーを参照してください。実際には、これは常に8の倍数でなければなりません。

だから

rsapubkey->bitlen = modulusLengthInBytes * 8; 

dwMagic値のあなたの設定があまりにも、正しくないようです。

rsapubkey->magic = 0x31415352; 

0x31415352はRSA_PUB_MAGICなので、自分自身を公開鍵と呼んでいます。 RSA_PRIV_MAGICが必要です(定数を使用する)。

rsapubkey->magic = RSA_PRIV_MAGIC; 

は、C#での作業ブロブライターである http://source.dot.net/#System.Security.Cryptography.Csp/System/Security/Cryptography/CapiHelper.Shared.cs,b7bc764e6deb34f5、と比較してください。

+0

あなたのアドバイスを試してみてください。他のアイデア? –

+0

あなたの「魔法」の価値も疑わしいようです。答えを更新し、.NET BLOBライターへのリンクを追加しました。 – bartonjs

+0

それは、おかげで、ありがとう。今後の参考として、ここで述べるように、魔法は0x32415352でなければなりません:https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx#priv_BLOB –

関連する問題