¿Es posible descifrar una cadena en C# que está cifrada a través de PowerShell y cómo?
La cadena se cifra a través de PowerShell como se muestra a continuación:
$pw = read-host "Enter Password" –AsSecureString ConvertFrom-SecureString $pw | out-file "C:\file.txt" Para volver a convertirlo con PowerShell, puedo usar estos comandos que llaman a la clase C# 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) El archivo contiene la cadena que se convirtió en una string("hello") .
Entonces, si abre el archivo file.txt , se ve similar a:
01000000d08c9ddf0115d1118c7a00c04fc297eb0100000052ded6c2db80e748933432e19b9de8b10000 000002000000000003660000c00000001000000016dc35885d76d07bab289eb9927cfc1e000000000480 0000a0000000100000003106cde553f45b08d13d89d11336170b280000005cc865c1ee1b57e84ed3d1a2 d3f2d0ec0f189b532e61c18d1f31444d6f119a1e8368477fd2d81f54140000000cb0262e58b08ae14f37 22c14c69684841b6b21cEl archivo de salida de ConvertFrom-SecureString que tiene es una cadena UTF-16 (contraseña) protegida con ProtectedData.Protect almacenado como un volcado hexadecimal.
Para revertir el uso de codificación:
// 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); El código anterior funciona cuando no especifica la -Key con ConvertFrom-SecureString . Luego, la cadena segura se protege con la API de protección de datos de Windows (DPAPI) . Como tal, la cadena debe decodificarse en la misma máquina y cuenta en la que se codificó.
Tenía el requisito de cifrar una cadena en Power Shell y descifrar en .Net. Busque la siguiente función para cifrar cualquier cadena. aquí (1..16) es una matriz de bytes .
function EncriptStringData { [CmdletBinding()] param ( [string] $PlainText ) $someSecureString = $PlainText | ConvertTo-SecureString -AsPlainText -Force $encryptedTextThatIcouldSaveToFile = ConvertFrom-SecureString -key (1..16) -SecureString $someSecureString return $encryptedTextThatIcouldSaveToFile }Ahora esta salida de cadena cifrada que he usado como entrada para mi programa .Net y obtengo el mismo texto sin formato como salida de mi programa .Net. Encuentre la siguiente función.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; namespace MyNameSpace { public class DecryptStringData { public string GetDecryptString(string EncriptData) { try { byte[] key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; byte[] asBytes = Convert.FromBase64String(EncriptData); string[] strArray = Encoding.Unicode.GetString(asBytes).Split(new[] { '|' }); if (strArray.Length != 3) throw new InvalidDataException("input had incorrect format"); byte[] magicHeader = HexStringToByteArray(EncriptData.Substring(0, 32)); byte[] rgbIV = Convert.FromBase64String(strArray[1]); byte[] cipherBytes = HexStringToByteArray(strArray[2]); SecureString str = new SecureString(); SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create(); //This for .Net 4.5 //Use this for .Net core // AesManaged algorithm = new AesManaged(); ICryptoTransform transform = algorithm.CreateDecryptor(key, rgbIV); using (var stream = new CryptoStream(new MemoryStream(cipherBytes), transform, CryptoStreamMode.Read)) { int numRed = 0; byte[] buffer = new byte[2]; // two bytes per unicode char while ((numRed = stream.Read(buffer, 0, buffer.Length)) > 0) { str.AppendChar(Encoding.Unicode.GetString(buffer).ToCharArray()[0]); } } string secretvalue = convertToUNSecureString(str); return secretvalue; } catch (Exception ex) { return ex.Message; } } public static byte[] HexStringToByteArray(String hex) { int NumberChars = hex.Length; byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; } public static string convertToUNSecureString(SecureString secstrPassword) { IntPtr unmanagedString = IntPtr.Zero; try { unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secstrPassword); return Marshal.PtrToStringUni(unmanagedString); } finally { Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); } } }}