Files
seraph/seraph/Seraph.Utility/crypt32.cs
2026-02-17 04:22:40 +01:00

79 lines
2.3 KiB
C#

namespace seraph.Seraph.Utility;
using System.Runtime.InteropServices;
using System.Text;
using System;
public static class Crypt32Wrapper
{
[DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CryptUnprotectData(
ref DATA_BLOB pDataIn,
out IntPtr ppszDataDescr,
IntPtr pOptionalEntropy,
IntPtr pvReserved,
IntPtr pPromptStruct,
int dwFlags,
out DATA_BLOB pDataOut);
[StructLayout(LayoutKind.Sequential)]
private struct DATA_BLOB
{
public int cbData;
public IntPtr pbData;
}
private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
public static string Decrypt(byte[] encryptedData)
{
if (encryptedData == null || encryptedData.Length == 0)
{
throw new ArgumentException("Encrypted data cannot be null or empty.");
}
var inBlob = new DATA_BLOB
{
cbData = encryptedData.Length,
pbData = Marshal.AllocHGlobal(encryptedData.Length)
};
Marshal.Copy(encryptedData, 0, inBlob.pbData, encryptedData.Length);
DATA_BLOB outBlob = new DATA_BLOB();
IntPtr descriptionPtr = IntPtr.Zero;
try
{
bool success = CryptUnprotectData(ref inBlob, out descriptionPtr, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
CRYPTPROTECT_UI_FORBIDDEN, out outBlob);
if (!success)
{
int errorCode = Marshal.GetLastWin32Error();
throw new InvalidOperationException($"Decryption failed with error code: {errorCode}");
}
if (outBlob.pbData == IntPtr.Zero)
{
throw new InvalidOperationException("Decryption failed: outBlob.pbData is null.");
}
byte[] decryptedData = new byte[outBlob.cbData];
Marshal.Copy(outBlob.pbData, decryptedData, 0, outBlob.cbData);
return Encoding.UTF8.GetString(decryptedData);
}
finally
{
Marshal.FreeHGlobal(inBlob.pbData);
if (outBlob.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(outBlob.pbData);
}
if (descriptionPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(descriptionPtr);
}
}
}
}