97 lines
3.3 KiB
C#
97 lines
3.3 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Security.Cryptography;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace RDP_Portal {
|
|||
|
/**
|
|||
|
* By ChipForster
|
|||
|
* https://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/
|
|||
|
*/
|
|||
|
class Mstscpw {
|
|||
|
private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
|
|||
|
|
|||
|
// Wrapper for the NULL handle or pointer.
|
|||
|
static private IntPtr NullPtr = ((IntPtr)((int)(0)));
|
|||
|
|
|||
|
// Wrapper for DPAPI CryptProtectData function.
|
|||
|
[DllImport( "crypt32.dll", SetLastError = true,
|
|||
|
CharSet = System.Runtime.InteropServices.CharSet.Auto )]
|
|||
|
|
|||
|
private static extern bool CryptProtectData(
|
|||
|
ref DATA_BLOB pPlainText,
|
|||
|
[MarshalAs(UnmanagedType.LPWStr)] string szDescription,
|
|||
|
IntPtr pEntroy,
|
|||
|
IntPtr pReserved,
|
|||
|
IntPtr pPrompt,
|
|||
|
int dwFlags,
|
|||
|
ref DATA_BLOB pCipherText);
|
|||
|
|
|||
|
// BLOB structure used to pass data to DPAPI functions.
|
|||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|||
|
internal struct DATA_BLOB {
|
|||
|
public int cbData;
|
|||
|
public IntPtr pbData;
|
|||
|
}
|
|||
|
|
|||
|
private static void InitBLOB(byte[] data, ref DATA_BLOB blob) {
|
|||
|
blob.pbData = Marshal.AllocHGlobal(data.Length);
|
|||
|
if (blob.pbData == IntPtr.Zero)
|
|||
|
throw new Exception( "Unable to allocate buffer for BLOB data." );
|
|||
|
|
|||
|
blob.cbData = data.Length;
|
|||
|
Marshal.Copy(data, 0, blob.pbData, data.Length);
|
|||
|
}
|
|||
|
|
|||
|
public string encryptpw(string pw) {
|
|||
|
byte[] pwba = Encoding.Unicode.GetBytes(pw);
|
|||
|
DATA_BLOB dataIn = new DATA_BLOB();
|
|||
|
DATA_BLOB dataOut = new DATA_BLOB();
|
|||
|
StringBuilder epwsb = new StringBuilder();
|
|||
|
try {
|
|||
|
try {
|
|||
|
InitBLOB(pwba, ref dataIn);
|
|||
|
} catch (Exception ex) {
|
|||
|
throw new Exception( "Cannot initialize dataIn BLOB.", ex );
|
|||
|
}
|
|||
|
|
|||
|
bool success = CryptProtectData(
|
|||
|
ref dataIn,
|
|||
|
"psw",
|
|||
|
NullPtr,
|
|||
|
NullPtr,
|
|||
|
NullPtr,
|
|||
|
CRYPTPROTECT_UI_FORBIDDEN,
|
|||
|
ref dataOut );
|
|||
|
|
|||
|
if (!success) {
|
|||
|
int errCode = Marshal.GetLastWin32Error();
|
|||
|
throw new Exception( "CryptProtectData failed.", new Win32Exception(errCode) );
|
|||
|
}
|
|||
|
|
|||
|
byte[] epwba = new byte[dataOut.cbData];
|
|||
|
Marshal.Copy(dataOut.pbData, epwba, 0, dataOut.cbData);
|
|||
|
|
|||
|
// Convert hex data to hex characters (suitable for a string)
|
|||
|
for (int i = 0; i < dataOut.cbData; i++) {
|
|||
|
epwsb.Append(Convert.ToString(epwba[i], 16).PadLeft(2, '0').ToUpper());
|
|||
|
}
|
|||
|
|
|||
|
} catch (Exception ex) {
|
|||
|
throw new Exception( "unable to encrypt data.", ex );
|
|||
|
} finally {
|
|||
|
if (dataIn.pbData != IntPtr.Zero)
|
|||
|
Marshal.FreeHGlobal(dataIn.pbData);
|
|||
|
|
|||
|
if (dataOut.pbData != IntPtr.Zero)
|
|||
|
Marshal.FreeHGlobal(dataOut.pbData);
|
|||
|
}
|
|||
|
|
|||
|
return epwsb.ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|