C# 使用securestring解密函数

C# 使用securestring解密函数,c#,wpf,cryptography,C#,Wpf,Cryptography,所以我在处理这个问题。我有一个解密函数,如下所示: public static bool FileDecrypt(string inputFile, string outputFile, SecureString password) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[32]; FileStream fsCry

所以我在处理这个问题。我有一个解密函数,如下所示:

public static bool FileDecrypt(string inputFile, string outputFile, SecureString password)
    {

        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        byte[] salt = new byte[32];

        FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
        fsCrypt.Read(salt, 0, salt.Length);

        RijndaelManaged AES = new RijndaelManaged();
        AES.KeySize = 256;
        AES.BlockSize = 128;
        var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
        AES.Key = key.GetBytes(AES.KeySize / 8);
        AES.IV = key.GetBytes(AES.BlockSize / 8);
        AES.Padding = PaddingMode.PKCS7;
        AES.Mode = CipherMode.CFB;

        CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);

        FileStream fsOut = new FileStream(outputFile, FileMode.Create);

            int read;
            byte[] buffer = new byte[1048576];

            try
            {
                while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
                    fsOut.Write(buffer, 0, read);
                }
            }
            catch (CryptographicException ex_CryptographicException)
            {
                fsOut.Close();
                fsCrypt.Close();
                LogWriter loger = new LogWriter("Cryptography error: " + ex_CryptographicException.ToString());
                return false;
            }
            catch (Exception ex)
            {
                fsOut.Close();
                fsCrypt.Close();
                LogWriter loger = new LogWriter("Cryptography error: " + ex.ToString());
                return false;
            }

            try
            {
                cs.Close();
            }
            catch (Exception ex)
            {
                fsCrypt.Close();
                fsOut.Close();
                LogWriter loger = new LogWriter("Error when closing Cryptostream. Error: " + ex.ToString());
                return false;
            }
            finally
            {
                fsOut.Close();
                fsCrypt.Close();
            }

    return true;


    }
但如果我们谈论安全性,我也希望使用SecureString作为密码,而不仅仅是字符串(人们会输入解密文件的密码,所以我不想让它只保存在普通字符串中); 问题是我真的不懂密码,它不是我的功能,我不想搞砸任何事情

如果我想使用Securestring作为参数,我得到:

 cannot convert from 'System.Security.SecureString' to 'char[]' 
关于:

我想我需要以某种方式将其转换为安全字节数组(如果存在:D)

有人能告诉我如何才能做到这一点吗?或者在使用后从内存中删除字符串就足够了

谢谢并致以最良好的祝愿

约翰


//编辑你可以关闭我在评论中得到答案的问题。谢谢

在任何情况下,您都需要字符串的字节来加密或解密它们。有可能得到它们(看)。现在可以将字节传递给加密方法

但这种非常复杂的方式并不能提高您的安全性。评论员们已经写过了——他们有更多(更容易)的方法来窃取密码

只是为了好玩:也许黑客可以以某种方式读取受害者的RAM。假设您使用的是
SecureString
,并对其进行加密。您的代码正在工作,并且在您的方法中是“安全的”但是等待-用户在哪里输入密码?在文本框中?该死,它在公羊里。
RAM中的某个地方会有密码,你无法阻止。这不是悲剧——密码只会在那里停留很短时间,而地址(RAM中)将永远不会相同

黑客/间谍软件从RAM中读取密码的成本非常高。所以,在这条路上进攻的机会很低

最后一点要注意的是:通常你不会加密或解密密码。你可以对密码进行哈希运算

编辑
哦,别介意我的最后一段。我认为您想加密密码,但您正在使用它进行加密。对不起

如果你用谷歌搜索,我相信有很多答案。然而,我已经使用这种方法好几年了。我从互联网上找到了它,然后根据我的需要进行了修改。如需快速参考,请参阅下文。版权归原作者所有(无论此人是谁)

您需要参考以下项目:

 using System.Runtime.InteropServices; //You need reference to this item.
方法如下:

 public static string unWrap(SecureString input_secure_string)
        {
            if (input_secure_string == null) return null;
            IntPtr _pointer = IntPtr.Zero; //Initiating a integer which can store a C++ pointer. Intptr is a type in C# which can store C or C++ pointer types.
            try
            {
                _pointer = Marshal.SecureStringToGlobalAllocUnicode(input_secure_string); // Native code method which converts secure string to string
                return Marshal.PtrToStringUni(_pointer); 
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally //Most important key part is this. After we return the converter string, we dispose the pointer from memory.
            {
                Marshal.ZeroFreeGlobalAllocUnicode(_pointer);
            }
        }

上述代码不包括SecureString代码。它只包含密码字符串。请包括给出errorMind的代码:“重要:我们不建议您在新开发中使用SecureString类。有关更多信息,请参阅SecureString不应在GitHub上使用”,另请参阅
SecureString
基本上不推荐使用;它不提供任何实用的安全性来抵御任何现实攻击——更具体地说,它不能可靠地保护人们认为它所做的攻击向量,任何伪装它的行为只是一厢情愿的想法:“人们将输入密码来解密文件,所以我不想让它在正常的字符串中保存在内存中”。拍摄键盘或使用键盘记录器盗取密码的可能性比攻击者破坏内存的可能性大多少?我想你们是对的。只是在使用后从内存中删除它。但我真的不明白为什么要有SecureString
 public static string unWrap(SecureString input_secure_string)
        {
            if (input_secure_string == null) return null;
            IntPtr _pointer = IntPtr.Zero; //Initiating a integer which can store a C++ pointer. Intptr is a type in C# which can store C or C++ pointer types.
            try
            {
                _pointer = Marshal.SecureStringToGlobalAllocUnicode(input_secure_string); // Native code method which converts secure string to string
                return Marshal.PtrToStringUni(_pointer); 
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally //Most important key part is this. After we return the converter string, we dispose the pointer from memory.
            {
                Marshal.ZeroFreeGlobalAllocUnicode(_pointer);
            }
        }