2011-07-11 73 views
0

我試圖用crypt32.dll來加密如下.rdp文件密碼:C#密碼不正確加密

internal static class CryptPassword 
{ 
#region KeyType enum 

public enum KeyType 
{ 
UserKey = 1, 
MachineKey 
} ; 

#endregion 

private const int CRYPTPROTECT_LOCAL_MACHINE = 0x4; 
private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1; 
private static readonly IntPtr NullPtr = ((IntPtr)((0))); 
private static KeyType defaultKeyType = KeyType.UserKey; 

public static byte[] DoRawEncryption(string strToEncrypt) 
{ 
byte[] cryptBytes = Encrypt(KeyType.UserKey, Encoding.UTF8.GetBytes(strToEncrypt), null, null); 

return cryptBytes; 
} 

// Wrapper for DPAPI CryptProtectData function. 
[DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
private static extern bool CryptProtectData(ref DATA_BLOB pPlainText, string szDescription, ref DATA_BLOB pEntropy, IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pCipherText); 

// Wrapper for DPAPI CryptUnprotectData function. 
[DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
private static extern bool CryptUnprotectData(ref DATA_BLOB pCipherText, ref string pszDescription, ref DATA_BLOB pEntropy, IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pPlainText); 

// BLOB structure used to pass data to DPAPI functions. 

private static void InitPrompt(ref CRYPTPROTECT_PROMPTSTRUCT ps) 
{ 
ps.cbSize = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT)); 
ps.dwPromptFlags = 0; 
ps.hwndApp = NullPtr; 
ps.szPrompt = null; 
} 

private static void InitBLOB(byte[] data, ref DATA_BLOB blob) 
{ 
// Use empty array for null parameter. 
if (data == null) 
data = new byte[0]; 

// Allocate memory for the BLOB data. 
blob.pbData = Marshal.AllocHGlobal(data.Length); 

// Make sure that memory allocation was successful. 
if (blob.pbData == IntPtr.Zero) 
throw new Exception("Unable to allocate data buffer for BLOB structure."); 

// Specify number of bytes in the BLOB. 
blob.cbData = data.Length; 

// Copy data from original source to the BLOB structure. 
Marshal.Copy(data, 0, blob.pbData, data.Length); 
} 

public static string Encrypt(string plainText) 
{ 
return Encrypt(defaultKeyType, plainText, String.Empty, String.Empty); 
} 

public static string Encrypt(KeyType keyType, string plainText) 
{ 
return Encrypt(keyType, plainText, String.Empty, String.Empty); 
} 

public static string Encrypt(KeyType keyType, string plainText, string entropy) 
{ 
return Encrypt(keyType, plainText, entropy, String.Empty); 
} 

public static string Encrypt(KeyType keyType, string plainText, string entropy, string description) 
{ 
// Make sure that parameters are valid. 
if (plainText == null) plainText = String.Empty; 
if (entropy == null) entropy = String.Empty; 

// Call encryption routine and convert returned bytes into a base64-encoded value. 
return Convert.ToBase64String(Encrypt(keyType, Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(entropy), description)); 
} 

public static byte[] Encrypt(KeyType keyType, byte[] plainTextBytes, byte[] entropyBytes, string description) 
{ 
// Make sure that parameters are valid. 
if (plainTextBytes == null) plainTextBytes = new byte[0]; 
if (entropyBytes == null) entropyBytes = new byte[0]; 
if (description == null) description = String.Empty; 

// Create BLOBs to hold data. 
DATA_BLOB plainTextBlob = new DATA_BLOB(); 
DATA_BLOB cipherTextBlob = new DATA_BLOB(); 
DATA_BLOB entropyBlob = new DATA_BLOB(); 

// We only need prompt structure because it is a required 
// parameter. 
CRYPTPROTECT_PROMPTSTRUCT prompt = new CRYPTPROTECT_PROMPTSTRUCT(); 
InitPrompt(ref prompt); 

try 
{ 
// Convert plaintext bytes into a BLOB structure. 
try 
{ 
InitBLOB(plainTextBytes, ref plainTextBlob); 
} 
catch (Exception ex) 
{ 
throw new Exception("Cannot initialize plaintext BLOB.", ex); 
} 

// Convert entropy bytes into a BLOB structure. 
try 
{ 
InitBLOB(entropyBytes, ref entropyBlob); 
} 
catch (Exception ex) 
{ 
throw new Exception("Cannot initialize entropy BLOB.", ex); 
} 

// Disable any types of UI. 
int flags = CRYPTPROTECT_UI_FORBIDDEN; 

// When using machine-specific key, set up machine flag. 
if (keyType == KeyType.MachineKey) 
flags |= CRYPTPROTECT_LOCAL_MACHINE; 

// Call DPAPI to encrypt data. 
bool success = CryptProtectData(ref plainTextBlob, description, ref entropyBlob, IntPtr.Zero, ref prompt, flags, ref cipherTextBlob); 
// Check the result. 
if (!success) 
{ 
// If operation failed, retrieve last Win32 error. 
int errCode = Marshal.GetLastWin32Error(); 

// Win32Exception will contain error message corresponding to the Windows error code. 
throw new Exception("CryptProtectData failed."); 
} 

// Allocate memory to hold ciphertext. 
byte[] cipherTextBytes = new byte[cipherTextBlob.cbData]; 

// Copy ciphertext from the BLOB to a byte array. 
Marshal.Copy(cipherTextBlob.pbData, cipherTextBytes, 0, cipherTextBlob.cbData); 

// Return the result. 
return cipherTextBytes; 
} 
catch (Exception ex) 
{ 
throw new Exception("DPAPI was unable to encrypt data.", ex); 
} 
// Free all memory allocated for BLOBs. 
finally 
{ 
if (plainTextBlob.pbData != IntPtr.Zero) 
Marshal.FreeHGlobal(plainTextBlob.pbData); 

if (cipherTextBlob.pbData != IntPtr.Zero) 
Marshal.FreeHGlobal(cipherTextBlob.pbData); 

if (entropyBlob.pbData != IntPtr.Zero) 
Marshal.FreeHGlobal(entropyBlob.pbData); 
} 
} 

#region Nested type: CRYPTPROTECT_PROMPTSTRUCT 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
internal struct CRYPTPROTECT_PROMPTSTRUCT 
{ 
public int cbSize; 
public int dwPromptFlags; 
public IntPtr hwndApp; 
public string szPrompt; 
} 
#endregion 

#region Nested type: DATA_BLOB 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
internal struct DATA_BLOB 
{ 
public int cbData; 
public IntPtr pbData; 
} 
#endregion 
} 

和下面稱之爲:

class Program 
{ 
    public static String EncryptedPassword; 
    static void Main(string[] args) 
    { 
     byte[] cryptBytes = CryptPassword.DoRawEncryption("t"); 
     EncryptedPassword = Encoding.UTF8.GetString(cryptBytes); 
     EncryptedPassword = BitConverter.ToString(cryptBytes).Replace("-", ""); 

    } 
} 

問題該結果不匹配與該加密的.rdp:

代碼加密結果:

01000000D08C9DDF0115D1118C7A00C04FC297EB01000000085A862EC951114CAEDC00A80522CC48000000000 
2000000000003660000A800000010000000D20EDDD67EC1BB9F0B1E996CA4A1930A0000000004800000A00000 
00100000003B458BC56D4D6C81CFD7CE797D31353C08000000A523707EC1C6963A14000000F1918840B926CF4 
887085B0FCFA5A1AD8E929D30 

加密使用http://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/

演示轉換器應用是:

01000000D08C9DDF0115D1118C7A00C04FC297EB010000002D0779E40801FB4984E12A8A519D599904000 
00008000000700073007700000003660000A800000010000000A9ABEDB349D432ECB0CC8CCF337ECB0F00 
00000004800000A00000001000000015F29360976A00EA2E85E9A1BBD9E123080000006C8B090A9CD09B7 
5140000003C77984DAD4134987D16113AF4FF0DF8BBBD392C 

請幫助!

回答

4

我不得不這樣做了一段時間後,我做了一個有點不同,但一個關鍵的一點是:你需要使用Unicode,不UTF8,在您的通話GetBytes會。

+0

我試圖使用Unicode呼叫得到同樣的結果,密碼不匹配 – Ragaei

+0

這裏的結果: – Ragaei

+0

「T」 應用: 01000000D08C9DDF0115D1118C7A00C04FC297EB0100000 02D0779E40801FB4984E12A8A519D599904000000080000 00700073007700000003660000A800000010000000877C1 887237D9D25678522CDDDAC54530000000004800000A000 000010000000E88E17CA4FB284F09A108A3F230BEB8F080 0000068BAA4AE9D029924140000006D3C481C7D4DCBD142 2504148BF6C489C0D712D5 – Ragaei