/
dalek
/
RDPTools
Обзор
Документация
Войти
/
dalek
/
RDPTools
Код
Запросы
0
Пакеты
0
Релизы
1
Аналитика
Безопасность
master
Services/RDPCryptographyService.cs
209 строк
5 KB
Николай Киреев
RDPCryptographyService.cs
20 июл 2026, 12:21
Верифицирован
20 июл 2026, 12:21
bbf7075
Код
Авторство
О чём код?
using System; using System.Runtime.InteropServices; using System.Text; namespace RDPTools.Services { public class RDPCryptographyService { private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1; [StructLayout(LayoutKind.Sequential)] private struct DATA_BLOB { public int cbData; public IntPtr pbData; } [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool CryptProtectData( ref DATA_BLOB pDataIn, string szDataDescr, IntPtr pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut); [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool CryptUnprotectData( ref DATA_BLOB pDataIn, IntPtr ppszDataDescr, IntPtr pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern IntPtr LocalFree(IntPtr hMem); public static string? CryptPassword(string password) { try { if (string.IsNullOrEmpty(password)) { return null; } byte[] passwordBytes = Encoding.Unicode.GetBytes(password); DATA_BLOB dataIn = new(); DATA_BLOB dataOut = new(); IntPtr pInputData = Marshal.AllocHGlobal(passwordBytes.Length); Marshal.Copy(passwordBytes, 0, pInputData, passwordBytes.Length); dataIn.cbData = passwordBytes.Length; dataIn.pbData = pInputData; bool result = CryptProtectData( ref dataIn, "psw", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, CRYPTPROTECT_UI_FORBIDDEN, ref dataOut); if (result) { byte[] encryptedData = new byte[dataOut.cbData]; Marshal.Copy(dataOut.pbData, encryptedData, 0, dataOut.cbData); LocalFree(dataOut.pbData); Marshal.FreeHGlobal(pInputData); string hexString = BitConverter.ToString(encryptedData).Replace("-", ""); return hexString; } Marshal.FreeHGlobal(pInputData); return null; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"CryptPassword error: {ex.Message}"); return null; } } public static string? UncryptPassword(string hexPassword) { try { if (string.IsNullOrEmpty(hexPassword)) { return null; } hexPassword = hexPassword.Trim(); if (hexPassword.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { hexPassword = hexPassword[2..]; } if (!IsHexString(hexPassword)) { throw new ArgumentException("Invalid hex string"); } byte[] encryptedBytes = HexStringToByteArray(hexPassword); DATA_BLOB dataIn = new(); DATA_BLOB dataOut = new(); IntPtr pEncryptedData = Marshal.AllocHGlobal(encryptedBytes.Length); Marshal.Copy(encryptedBytes, 0, pEncryptedData, encryptedBytes.Length); dataIn.cbData = encryptedBytes.Length; dataIn.pbData = pEncryptedData; bool result = CryptUnprotectData( ref dataIn, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, CRYPTPROTECT_UI_FORBIDDEN, ref dataOut); Marshal.FreeHGlobal(pEncryptedData); if (result) { byte[] decryptedData = new byte[dataOut.cbData]; Marshal.Copy(dataOut.pbData, decryptedData, 0, dataOut.cbData); LocalFree(dataOut.pbData); string decryptedPassword = Encoding.Unicode.GetString(decryptedData); int nullIndex = decryptedPassword.IndexOf('\0'); if (nullIndex >= 0) { decryptedPassword = decryptedPassword[..nullIndex]; } return decryptedPassword; } else { int error = Marshal.GetLastWin32Error(); System.Diagnostics.Debug.WriteLine($"CryptUnprotectData failed with error: {error}"); return null; } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"UncryptPassword error: {ex.Message}"); return null; } } private static bool IsHexString(string hex) { if (string.IsNullOrEmpty(hex)) { return false; } if (hex.Length % 2 != 0) { return false; } foreach (char c in hex) { if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) { return false; } } return true; } private static byte[] HexStringToByteArray(string hex) { int length = hex.Length; byte[] bytes = new byte[length / 2]; for (int i = 0; i < length; i += 2) { bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return bytes; } } }