У меня есть 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, что появляется данные должны быть прочитаны и написаны правильно, но дешифрование не выполняется.
спасибо за вашу помощь
Ben - Это именно то, что происходило/происходило. Спасибо. – pithhelmet