Is it possible to decrypt a string in C# which is encrypted via PowerShell and how?
The string is encrypted via PowerShell as below:
$pw = read-host "Enter Password" –AsSecureString
ConvertFrom-SecureString $pw | out-file "C:\file.txt"
To convert it back with PowerShell I can use these commands that call C# class System.Runtime.InteropServices.Marshal
.
$pwdSec = Get-Content "C:\file.txt" | ConvertTo-SecureString
$bPswd = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwdSec)
$pswd = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bPswd)
File contains the string that has been converted to an encrypted standard string("hello")
.
So if open the file.txt
file, it looks similar to:
01000000d08c9ddf0115d1118c7a00c04fc297eb0100000052ded6c2db80e748933432e19b9de8b10000
000002000000000003660000c00000001000000016dc35885d76d07bab289eb9927cfc1e000000000480
0000a0000000100000003106cde553f45b08d13d89d11336170b280000005cc865c1ee1b57e84ed3d1a2
d3f2d0ec0f189b532e61c18d1f31444d6f119a1e8368477fd2d81f54140000000cb0262e58b08ae14f37
22c14c69684841b6b21c
The output file from the ConvertFrom-SecureString
you have is a UTF-16 (password) string protected with the ProtectedData.Protect
stored as a hex dump.
Do revert the encoding use:
// Read file to string
string exportedData = File.ReadAllText(@"file.txt");
// Remove all new-lines
exportedData = exportedData.Replace(Environment.NewLine, "");
// Convert the hex dump to byte array
int length = exportedData.Length / 2;
byte[] encryptedData = new byte[length];
for (int index = 0; index < length; ++index)
{
encryptedData[index] =
byte.Parse(
exportedData.Substring(2 * index, 2),
NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
// Decrypt the byte array to Unicode byte array
byte[] data =
ProtectedData.Unprotect(encryptedData, (byte[])null, DataProtectionScope.CurrentUser);
// Convert Unicode byte array to string
string password = Encoding.Unicode.GetString(data);
The above code works, when you do not specify the -Key
with the ConvertFrom-SecureString
. The secure string is then protected with Windows Data Protection API (DPAPI). As such the string has to be decoded on the same machine and account, as it was encoded.