【问题标题】:How to decrypt a string in C# which is encrypted via PowerShell如何在 C# 中解密通过 PowerShell 加密的字符串
【发布时间】:2015-06-16 04:50:19
【问题描述】:

是否可以在 C# 中解密通过 PowerShell 加密的字符串以及如何解密?

字符串通过PowerShell加密如下:

$pw = read-host "Enter Password" –AsSecureString

ConvertFrom-SecureString $pw | out-file "C:\file.txt"

要使用 PowerShell 将其转换回来,我可以使用这些调用 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)

文件包含已转换为加密标准string("hello") 的字符串。

所以如果打开file.txt文件,它看起来类似于:

01000000d08c9ddf0115d1118c7a00c04fc297eb0100000052ded6c2db80e748933432e19b9de8b10000
000002000000000003660000c00000001000000016dc35885d76d07bab289eb9927cfc1e000000000480
0000a0000000100000003106cde553f45b08d13d89d11336170b280000005cc865c1ee1b57e84ed3d1a2
d3f2d0ec0f189b532e61c18d1f31444d6f119a1e8368477fd2d81f54140000000cb0262e58b08ae14f37
22c14c69684841b6b21c

【问题讨论】:

标签: c# .net powershell encryption securestring


【解决方案1】:

您拥有的ConvertFrom-SecureString 的输出文件是一个UTF-16(密码)字符串,并以十六进制转储形式存储为ProtectedData.Protect

要恢复编码使用:

// 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);

上面的代码有效,当你没有用ConvertFrom-SecureString指定-Key。然后使用Windows Data Protection API (DPAPI) 保护安全字符串。因此,字符串必须在与编码相同的机器和帐户上解码。

【讨论】:

    【解决方案2】:

    我需要在 power shell 中加密字符串并在 .Net 中解密 请找到以下函数来加密任何字符串。这里 (1..16) 是一个字节数组

    function EncriptStringData {
    [CmdletBinding()]
    param (
        [string] $PlainText        
    )
    $someSecureString = $PlainText | ConvertTo-SecureString -AsPlainText -Force
    $encryptedTextThatIcouldSaveToFile =  ConvertFrom-SecureString -key (1..16) -SecureString $someSecureString
    
    return $encryptedTextThatIcouldSaveToFile
    }
    

    现在,我将这个加密字符串输出用作我的 .Net 程序的输入,并获得与我的 .Net 程序输出相同的纯文本。 请找到以下函数。

    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);
            }
        }
    
    }
    

    }

    【讨论】:

    • 你就是那个男人。这确实很复杂,但很有效。
    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多