2013-06-09 3 views
2

У меня есть C++ приложение (32 бит), который будет принимать введенную строку, зашифровать его, используя блок кода с именем WriteProtectedStringValueToRegistryC++ шифрования, C# дешифрования = отказ

LONG WriteProtectedStringValueToRegistry(LPCTSTR subKey, LPCTSTR valueName, LPCTSTR  value) 
{size_t len = strlen(value); 

if (!subKey || !valueName) 
    return ERROR_INVALID_DATA; 

LONG result = 0; 
DWORD keyCreationResult = 0; 
HKEY newKey; 

// Create a new key or open existing key. 
result = RegCreateKeyEx(
    HKEY_LOCAL_MACHINE, 
    subKey, 
    0, 
    NULL, 
    0, 
    KEY_ALL_ACCESS, 
    NULL, 
    &newKey, 
    &keyCreationResult); 
if (ERROR_SUCCESS != result) 
{ 
    return result; 
} 

if (keyCreationResult == REG_OPENED_EXISTING_KEY) 
{ 
    WriteLog("Opened existing key '%s'\n", subKey); 
} 
else 
{ 
    WriteLog("Created new key '%s'\n", subKey); 
} 

DATA_BLOB unencryptedData, encryptedData; 
unencryptedData.pbData = (BYTE *)value; 

// Save the NULL character in the data 
// We need to multiply the length of the string by the 
// size of the data contained therein to support multi- 
// byte character sets. 
unencryptedData.cbData = (len + 1) * sizeof(*value); 
if (!CryptProtectData(
    &unencryptedData, 
    L"My Encrypted Data", 
    NULL, 
    NULL, 
    NULL, 
    0, 
    &encryptedData)) 
{ 
    RegCloseKey(newKey); 
    return GetLastError(); 
} 

// OK, so now we can save the data to the registry. 
result = RegSetValueEx(
    newKey, 
    valueName, 
    0, 
    REG_BINARY, 
    encryptedData.pbData, 
    encryptedData.cbData); 

// Free the encrypted data buffer 
LocalFree(encryptedData.pbData); 
RegCloseKey(newKey); 

return result; 
} 

Теперь - в другом приложении (C#, встроенный для любого процессора) Я использую класс DPAPI от Microsoft для дешифрования двоичной строки, считанной из реестра.

private void btnRead_Click(object sender, EventArgs e) 
{ 
    try 
    { 
    RegistryKey rKey1 = Registry.LocalMachine; 
    rKey1 = rKey1.OpenSubKey(@"SOFTWARE\XXX\XXX\Credentials", true); 

    var value = (byte[])rKey1.GetValue("UserName"); 
    var valueAsString = BitConverter.ToString(value); 

    string decrypted = DPAPI.Decrypt(EncodeTo64(valueAsString)); 
    } 
    catch (Exception ex) 
    { 
    while (ex != null) 
    { 
     Console.WriteLine(ex.Message); 
     ex = ex.InnerException; 
    } 
    } 
} 

Использование испытательного стенда, я могу подтвердить данные, записанных в реестр может быть зашифрован и в незашифрованном виде в C++ программы, а с помощью другого испытательного стенда, я могу подтвердить шифровать и дешифровать работаю в C# заявление.

string xx = DPAPI.Encrypt("Administrator"); 
    string yy = DPAPI.Decrypt(xx); 
    // works encrypt and decrypt 

    byte[] data; 
    data = Convert.FromBase64String(xx); 
    rKey2.SetValue("UserNamecsharp", data, RegistryValueKind.Binary); 


    byte[] value = (byte[])rKey1.GetValue("UserName"); 
    var valueAsString = Convert.ToBase64String(value); 

    string decrypted = DPAPI.Decrypt(valueAsString); 

Оказывается начальные значения в реестре одинаковы, и работает через отладчик, они кажутся очень близкими - вплоть до четырех элементов а

valueAsString
«AQAAANCMnd8BFdERjHoAwE/Cl + sBAAAAesG + С/0ymUSov + q7G6U0rAAAAAAkAAAATQB5ACAARQBuAGMAcgB5AHAAdABlAGQAIABEAGEAdABhAAAAA2YAAKgAAAAQAAAAhMQNYP/ECV0uWNQJNwR0DQAAAAAEgAAAoAAAABAAAAAusIzWvKtWfIE25su1nBkWEAAAACWxuZ2lz12ON/uOafeqdfcUAAAAs7rYAvpeXoSH191clwcFXxmIA9M = "строка

хх" AQAAANCMnd8BFdERjHoAwE/CI + sBAAAA3lfKy0QLx0KeGBAy9xuu oAAAAAACAAAAAAADZgAAwAAAABAAAAA7y9SEsVpdsVoCO78Vlq + 3AAAAAASAAACgAAAAEAAAAG1Ssj5xjVqBhCm2rK9oUtIQAAAA07Fyyoq6vK2OHJ1ygG4t8RQAAACZp6TmW2EBsu7kPVlf05D + jkVC7w ==»строка

Вот содержимое реестра для них ...

"UserName"= шестигранной: 01,00,00,00, d0,8c, 9г, ДФ, 01 , 15, d1,11,8c, 7a, 00, c0,4f, c2,97, eb, 01, \ 00,00,00,7a, c1, be, 0b, fd, 32,99,44, a8 , bf, ea, bb, 1b, a5,34, ac, 00,00,00,00,24,00, \ 00,00,4d, 00,79,00,20,00,45,00,6e , 00,63,00,72,00,79,00,70,00,74,00,65,00,64, \ 00,20,00,44,00,61,00,74,00,61 , 00,00,00,03,66,00,00, a8,00,00,00,10,00,00,00, \ 84, c4,0d, 60, ff, c4,09,5d, 2e , 58, d4,09,37,04,74,0d, 00,00,00,00,04,80,00,00, a0, \ 0 0,00,00,10,00,00,00,2e, b0,8c, d 6, BC, AB, 56,7c, 81,36, е6, CB, b5,9c, 19,16,10,00, \ 00,00,25, b1, b9,9d, a5, cf, 5d, 8e, 37, fb, 8e, 69, f7, aa, 75, f7,14,00,00,00, b3, ba, d8, \ 02, fa, 5e, 5e, 84,87, d7, dd, 5c, 97,07,05,5f, 19,88,03, d3

"UserNamecsharp" = hex: 01,00 , 00,00, d0,8c, 9d, df, 01,15, d1,11,8c, 7a, 00, c0,4f, c2,97, eb, 01, \ 00,00,00, de, 57 , ca, cb, 44,0b, c7,42,9e, 18,10,32, f7,1b, ae, a0,00,00,00,00,02,00, \ 00,00,00,00 , 03,66,00,00, c0,00,00,00,10,00,00,00,3b, cb, d4,84, b1,5a, 5d, b1,5a, \ 02,3b, bf , 15,96, af, b7,00,00,00,00,04,80,00,00, a0,00,00,00,10,00,00,00,6d, 52, \ b2,3e , 71,8d, 5a, 81,84,29, b6, ac, af, 68,52, d2,10,00,00,00, d3, b1,72, ca, 8a, ba, bc, \ ad , 8e, 1c, 9d, 72,80,6e, 2d, f1,14,00,00,00,99, а7, а4, e6,5b, 61 , 01, b2, ee, e4,3d, 59, \ 5f, d3,90, fe, 8e, 45,42, ef

Мне что-то не хватает, используя те же подпрограммы cypt32.dll, что появляется данные должны быть прочитаны и написаны правильно, но дешифрование не выполняется.

спасибо за вашу помощь

ответ

2

На первый взгляд, кажется, что вы используете 8-битных полукокса строк («строка») вместо Юникода строк (L «мля» или wchar_t *) в вашем C++ код. C# использует Unicode для строк. Возможно, поэтому вы получаете разные результаты. Моей первой проверкой было бы удостовериться, что я передаю строки C++ как unicode.

Удачи, надеюсь, это поможет. :)

+0

Ben - Это именно то, что происходило/происходило. Спасибо. – pithhelmet

Смежные вопросы