gpt4 book ai didi

c# - 如何使用 ConvertTo-SecureString

转载 作者:太空狗 更新时间:2023-10-29 20:00:00 25 4
gpt4 key购买 nike

假设我需要在 Powershell 中执行此操作:

    $SecurePass = Get-Content $CredPath | ConvertTo-SecureString -Key (1..16)
[String]$CleartextPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($CredPass));

$CredPath 的内容是一个包含 ConvertFrom-SecureString -Key (1..16) 输出的文件。

如何在 C#/.NET 中完成 ConvertTo-SecureString -key (1..16) 部分?

我知道如何创建 SecureString,但我不确定应该如何处理加密。

我是使用 AES 加密每个字符,还是解密字符串然后为每个字符创建一个安全字符串?

我对密码学几乎一无所知,但根据我收集到的信息,我可能只想使用 C# 调用 Powershell 命令。

作为引用,我在这里找到了一篇关于 AES 加密/解密的类似帖子: Using AES encryption in C#

更新

I have reviewed the link Keith posted ,但我面临更多的未知数。 DecryptStringFromBytes_Aes 采用三个参数:

static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)

第一个参数是一个字节数组,表示加密的文本。这里的问题是,字符串在字节数组中应该如何表示呢?它应该用编码还是不用编码来表示?

byte[] ciphertext = Encoding.ASCII.GetBytes(encrypted_text);
byte[] ciphertext = Encoding.UTF8.GetBytes(encrypted_text);
byte[] ciphertext = Encoding.Unicode.GetBytes(encrypted_text);

byte[] ciphertext = new byte[encrypted_password.Length * sizeof(char)];
System.Buffer.BlockCopy(encrypted_password.ToCharArray(), 0, text, 0, text.Length);

第二个字节数组是键,应该只是一个整数数组:

byte[] key = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };

第三个字节数组是一个“初始化向量”——看起来 Aes.Create() 调用会随机生成一个 byte[] for IV。阅读周围,我发现我可能需要使用相同的 IV。由于 ConvertFrom-SecureString 和 ConvertTo-SecureString 能够仅使用 key 进行加密/解密,因此我假设 IV[] 可以是随机的 - 或者 - 具有静态定义。

我还没有找到一个成功的组合,但我会继续努力。

最佳答案

我知道这是一个旧帖子。我发布这个是为了完整性和后代,因为我在 MSDN 或 stackoverflow 上找不到完整的答案。它会在这里,以防我需要再次这样做。

它是 powershell 的 ConvertTo-SecureString 的 C# 实现,具有 AES 加密(通过使用 -key 选项打开)。我将把它留作练习,编写 ConvertFrom-SecureString 的 C# 实现。

# forward direction
[securestring] $someSecureString = read-host -assecurestring
[string] $psProtectedString = ConvertFrom-SecureString -key (1..16) -SecureString $someSecureString
# reverse direction
$back = ConvertTo-SecureString -string $psProtectedString -key (1..16)

我的工作是合并答案并重新安排 user2748365 的答案以使其更具可读性并添加教育评论!我还解决了采用子字符串的问题——在撰写本文时,他的代码在 strArray 中只有两个元素。

using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Globalization;

// psProtectedString - this is the output from
// powershell> $psProtectedString = ConvertFrom-SecureString -SecureString $aSecureString -key (1..16)
// key - make sure you add size checking
// notes: this will throw an cryptographic invalid padding exception if it cannot decrypt correctly (wrong key)
public static SecureString ConvertToSecureString(string psProtectedString, byte[] key)
{
// '|' is indeed the separater
byte[] asBytes = Convert.FromBase64String( psProtectedString );
string[] strArray = Encoding.Unicode.GetString(asBytes).Split(new[] { '|' });

if (strArray.Length != 3) throw new InvalidDataException("input had incorrect format");

// strArray[0] is a static/magic header or signature (different passwords produce
// the same header) It unused in our case, looks like 16 bytes as hex-string
// you know strArray[1] is a base64 string by the '=' at the end
// the IV is shorter than the body, and you can verify that it is the IV,
// because it is exactly 16bytes=128bits and it decrypts the password correctly
// you know strArray[2] is a hex-string because it is [0-9a-f]
byte[] magicHeader = HexStringToByteArray(encrypted.Substring(0, 32));
byte[] rgbIV = Convert.FromBase64String(strArray[1]);
byte[] cipherBytes = HexStringToByteArray(strArray[2]);

// setup the decrypter
SecureString str = new SecureString();
SymmetricAlgorithm algorithm = SymmetricAlgorithm.Create();
ICryptoTransform transform = algorithm.CreateDecryptor(key, rgbIV);
using (var stream = new CryptoStream(new MemoryStream(cipherBytes), transform, CryptoStreamMode.Read))
{
// using this silly loop format to loop one char at a time
// so we never store the entire password naked in memory
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]);
}
}

//
// non-production code
// recover the SecureString; just to check
// from http://stackoverflow.com/questions/818704/how-to-convert-securestring-to-system-string
//
IntPtr valuePtr = IntPtr.Zero;
string secureStringValue = "";
try
{
// get the string back
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(str);
secureStringValue = Marshal.PtrToStringUni(valuePtr);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
}

return str;
}
// from http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa
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 SecureString DecryptPassword( string psPasswordFile, byte[] key )
{
if( ! File.Exists(psPasswordFile)) throw new ArgumentException("file does not exist: " + psPasswordFile);

string formattedCipherText = File.ReadAllText( psPasswordFile );

return ConvertToSecureString(formattedCipherText, key);
}

关于c# - 如何使用 ConvertTo-SecureString,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13633826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com