Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要硬编码密码吗_C#_Winforms_Encryption_Passwords - Fatal编程技术网

C# 需要硬编码密码吗

C# 需要硬编码密码吗,c#,winforms,encryption,passwords,C#,Winforms,Encryption,Passwords,我正在做这个应用程序,它取决于存储在xml文件中的设置。此文件应加密,其中的值由负责创建应用程序设置的人员提供,并用于根据用户安装的版本确定可用的功能选项 我需要一种在我的软件中存储硬编码密码的方法,以便能够在运行时解密该文件并读取其中的值,以查看用户可以访问应用程序的哪些功能 请记住,此文件不应编辑,而是作为软件的一部分提供的 我没有提供任何代码,因为它更多的是设计问题,而不是编码问题 我知道硬编码密码是愚蠢的,但我没有选择。如果您将应用程序提供给不可信的用户(即,这是一个桌面应用程序,而不是

我正在做这个应用程序,它取决于存储在xml文件中的设置。此文件应加密,其中的值由负责创建应用程序设置的人员提供,并用于根据用户安装的版本确定可用的功能选项

我需要一种在我的软件中存储硬编码密码的方法,以便能够在运行时解密该文件并读取其中的值,以查看用户可以访问应用程序的哪些功能

请记住,此文件不应编辑,而是作为软件的一部分提供的

我没有提供任何代码,因为它更多的是设计问题,而不是编码问题


我知道硬编码密码是愚蠢的,但我没有选择。

如果您将应用程序提供给不可信的用户(即,这是一个桌面应用程序,而不是运行在用户无法直接访问的[ASP]服务器上的代码),那么您将无能为力

internal const string XmlPassword = "This is more like security through "+
+"obfuscation than real security.  If it fits your purposes, cool, but you "+
+"might want to consider using real encryption, like public key encryption";
如果您将代码提供给将解密配置文件的用户,那么在某个时刻,他们将能够自己访问该文件。如果你投入时间/精力/金钱,你可以让它变得更难,甚至可能更难,但你不能让它变得不可能。以下是他们可以做的一些事情:

  • 反编译程序并查找
    password=“12345”
    代码行
  • 监控程序的内存;查看它何时加载XML文件,并尝试在内存中查找该文件的解密版本
  • 找到读取解密的XML文件的代码部分,并相应地执行一些操作,然后更改代码,使其始终执行他们想要的任何操作,而不管文件中有什么内容(基本上只是注释掉
    if
    检查)
  • 您可以采取一些措施使上述步骤更加困难(但并非不可能),包括:

  • 混淆代码
  • 签署你的代码
  • 做一些随机的、毫无意义的事情来试图混淆代码嗅探器(例如玩shell游戏,有3个文件,全部读取,全部解密,然后有2个文件实际上没有被使用)
  • 将配置文件发送到您的web服务进行解密,而不是在本地对其进行解密。(这可以通过嗅探网络中的解密结果来解决)
  • 拥有一个您查询的web服务,以查看用户是否有权执行您想要的操作(同样,这可以通过嗅探/欺骗网络连接来解决)
  • 现在,根据“某物”是什么,可以通过不给用户最初执行“某物”的代码来阻止用户执行“某物”。这些(如果编码正确,可能)是不可破解的:

  • 在服务器上执行此操作。
  • 有一个web服务来完成一些敏感的工作。桌面应用程序只管理UI或其他非敏感任务。如果你这样做,用户只能破坏你给他们的代码
  • 让整个应用程序成为一个网站,或者其他基于服务器的应用程序(比如MMORPG),如果没有服务器,它根本无法运行;它几乎完成了所有敏感(和非敏感)工作

  • 请注意,唯一真正的解决方案要求所有用户在使用应用程序时都可以使用internet连接;他们不能脱机。

    一种方法是始终根据文件的某个哈希值对设置文件进行加密。然后,您的软件可以使用与密钥相同的哈希值对文件进行解密

    因此,您基本上要执行以下操作:

  • 获取文件名(和/或文件大小的其他属性)
  • 计算文件名的哈希值
  • 使用该散列来解密文件
  • 不是说这是一个好方法,或者说这是我个人在任何类型的生产软件中使用的方法,但至少你不依赖于代码中的纯文本或分散字符串,它让你可以灵活地更改设置文件名并依赖于加密约定


    同样,这可能只是“将密钥存储在源代码中”解决方案之上的一步。

    如果我正确理解了问题-OP需要解密使用某种类型的第三方软件包提供的文件(已加密),并且他已从软件的原始发布者处获得解密密码(密钥)

    我会做一些类似于Itsmart建议的事情,只是不加密文件,而是加密提供的密码,将加密的密码存储在配置文件中,然后在运行时读取和解密密码,并使用它来解密文件

    通过这种方式,您不需要在源代码中硬编码明文密码,以便轻松嗅出。通过将其保存在配置文件中,您可以在将来根据需要轻松更改密码

    对评论的答复:

    我使用AES256

    我使用此类来加密/解密:

    #region Preprocessor Directives
    
    # if __FRAMEWORK_V35 || __FRAMEWORK_V4
    #define __DotNet35Plus
    #endif
    
    #if !__DotNet35Plus
    #warning AES implementation used by this compile of the library is not NIST certified as FIPS 140-2 compliant
    #endif
    
    #endregion
    
    #region Namespaces
    using System;
    using System.Security.Cryptography;
    using System.IO;
    using System.Text;
    using System.Threading;
    using System.Runtime.Serialization.Formatters.Binary;
    #endregion
    
    namespace Simple
    {
        public static class AES256Encryption
        {
            private static readonly object _lock = new object();
            private const Int32 KeySize = 256;
    #if __DotNet35Plus
            private static AesCryptoServiceProvider thisCSP = new AesCryptoServiceProvider();
    #else
            private static RijndaelManaged thisCSP = new RijndaelManaged();
    #endif
            private static MemoryStream msEncrypt = new MemoryStream();
            private static CryptoStream csEncrypt;
            private static MemoryStream msDecrypt = new MemoryStream();
            private static CryptoStream csDecrypt;
    
            public enum stringIOType
            {
                base64EncodedString = 0,
                HexEncodedString = 1
            }
    
            public static bool NISTCertified()
            {
    #if __DotNet35Plus
                return true;
    #else
                return false;
    #endif
            }
    
            #region Encryption Methods
            public static byte[] encryptBytes(byte[] Value, string PassPhrase, Encoding PassPhraseEncoding)
            {
                try
                {
                    Monitor.Enter(_lock);
                    return encryptBytes(Value, getKeyFromPassPhrase(PassPhrase, PassPhraseEncoding), getIVFromPassPhrase(PassPhrase, PassPhraseEncoding));
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] encryptBytes(byte[] Value, byte[] Key, byte[] IV)
            {
                try
                {
                    Monitor.Enter(_lock);
    #if __DotNet35Plus
                    thisCSP = new AesCryptoServiceProvider();
    #else
                    thisCSP = new RijndaelManaged();
    #endif
                    thisCSP.KeySize = KeySize;
                    Int32 bitLength = Key.Length * 8;
                    if (bitLength != thisCSP.KeySize)
                    {
                        throw new ArgumentException("The supplied key's length [" + bitLength.ToString() + " bits] is not a valid key size for the AES-256 algorithm.", "Key");
                    }
                    bitLength = IV.Length * 8;
                    if (bitLength != thisCSP.BlockSize)
                    {
                        throw new ArgumentException("The supplied IV's length [" + bitLength.ToString() + " bits] is not a valid IV size for the AES-256 algorithm.", "IV");
                    }
                    ICryptoTransform Encryptor = thisCSP.CreateEncryptor(Key, IV);
                    msEncrypt = new MemoryStream();
                    csEncrypt = new CryptoStream(msEncrypt, Encryptor, CryptoStreamMode.Write);
                    csEncrypt.Write(Value, 0, Value.Length);
                    csEncrypt.FlushFinalBlock();
                    Encryptor.Dispose();
                    Encryptor = null;
                    msEncrypt.Close();
                    return msEncrypt.ToArray();
                }
                finally
                {
                    thisCSP = null;
                    Monitor.Exit(_lock);
                }
            }
    
            public static string encryptString(string Value, string PassPhrase, Encoding PassPhraseEncoding, Encoding inputEncoding, stringIOType outputType)
            {
                try
                {
                    Monitor.Enter(_lock);
                    return encryptString(Value, getKeyFromPassPhrase(PassPhrase, PassPhraseEncoding), getIVFromPassPhrase(PassPhrase, PassPhraseEncoding), inputEncoding, outputType);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static string encryptString(string Value, byte[] Key, byte[] IV, Encoding inputEncoding, stringIOType outputType)
            {
                try
                {
                    Monitor.Enter(_lock);
                    byte[] baseValue = (byte[])Array.CreateInstance(typeof(byte), inputEncoding.GetByteCount(Value));
                    baseValue = inputEncoding.GetBytes(Value);
                    switch(outputType)
                    {
                        case stringIOType.base64EncodedString:
                            return Convert.ToBase64String(encryptBytes(baseValue, Key, IV));
                        case stringIOType.HexEncodedString:
                            return ByteArrayToHexString(encryptBytes(baseValue, Key, IV));
                        default:
                            return Convert.ToBase64String(encryptBytes(baseValue, Key, IV));
                    }
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
            #endregion
    
            #region Decryption Methods
            public static byte[] decryptBytes(byte[] Value, string PassPhrase, Encoding PassPhraseEncoding)
            {
                try
                {
                    Monitor.Enter(_lock);
                    return decryptBytes(Value, getKeyFromPassPhrase(PassPhrase, PassPhraseEncoding), getIVFromPassPhrase(PassPhrase, PassPhraseEncoding));
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] decryptBytes(byte[] Value, byte[] Key, byte[] IV)
            {
                try
                {
                    Monitor.Enter(_lock);
    #if __DotNet35Plus
                    thisCSP = new AesCryptoServiceProvider();
    #else
                    thisCSP = new RijndaelManaged();
    #endif
                    thisCSP.KeySize = KeySize;
                    Int32 bitLength = Key.Length * 8;
                    if (bitLength != thisCSP.KeySize)
                    {
                        throw new ArgumentException("The supplied key's length [" + bitLength.ToString() + " bits] is not a valid key size for the AES-256 algorithm.", "Key");
                    }
                    bitLength = IV.Length * 8;
                    if (bitLength != thisCSP.BlockSize)
                    {
                        throw new ArgumentException("The supplied IV's length [" + bitLength.ToString() + " bits] is not a valid IV size for the AES-256 algorithm.", "IV");
                    }
                    try
                    {
                        byte[] Decrypted;
                        ICryptoTransform Decryptor = thisCSP.CreateDecryptor(Key, IV);
                        msDecrypt = new MemoryStream(Value);
                        csDecrypt = new CryptoStream(msDecrypt, Decryptor, CryptoStreamMode.Read);
                        Decrypted = (byte[])Array.CreateInstance(typeof(byte), msDecrypt.Length);
                        csDecrypt.Read(Decrypted, 0, Decrypted.Length);
                        Decryptor.Dispose();
                        Decryptor = null;
                        msDecrypt.Close();
                        Int32 trimCount = 0;
                        // Remove any block padding left over from encryption algorithm before returning
                        for (Int32 i = Decrypted.Length - 1; i >= 0; i--)
                        {
                            if (Decrypted[i] == 0) { trimCount++; } else { break; }
                        }
                        if (trimCount > 0)
                        {
                            byte[] buffer = (byte[])Array.CreateInstance(typeof(byte), Decrypted.Length - trimCount);
                            Array.ConstrainedCopy(Decrypted, 0, buffer, 0, buffer.Length);
                            Array.Clear(Decrypted, 0, Decrypted.Length);
                            Array.Resize<byte>(ref Decrypted, buffer.Length);
                            Array.Copy(buffer, Decrypted, buffer.Length);
                            buffer = null;
                        }
                        return Decrypted;
                    }
                    finally
                    {
                        thisCSP = null;
                    }
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static string decryptString(string Value, string PassPhrase, Encoding PassPhraseEncoding, stringIOType inputType, Encoding outputEncoding)
            {
                try
                {
                    Monitor.Enter(_lock);
                    return decryptString(Value, getKeyFromPassPhrase(PassPhrase, PassPhraseEncoding), getIVFromPassPhrase(PassPhrase, PassPhraseEncoding), inputType, outputEncoding);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static string decryptString(string Value, byte[] Key, byte[] IV, stringIOType inputType, Encoding outputEncoding)
            {
                try
                {
                    Monitor.Enter(_lock);
                    byte[] baseValue;
                    switch (inputType)
                    {
                        case stringIOType.base64EncodedString:
                            baseValue = Convert.FromBase64String(Value);
                            break;
                        case stringIOType.HexEncodedString:
                            baseValue = HexStringToByteArray(Value);
                            break;
                        default:
                            baseValue = Convert.FromBase64String(Value);
                            break;
                    }
                    return outputEncoding.GetString(decryptBytes(baseValue, Key, IV));
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
            #endregion
    
            #region Key/Digest Generation Methods
            public static byte[] getKeyFromPassPhrase(string PassPhrase, Encoding encoder)
            {
                Monitor.Enter(_lock);
                try
                {
                    return getDigest(PassPhrase, encoder, 32);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] getIVFromPassPhrase(string PassPhrase, Encoding encoder)
            {
                Monitor.Enter(_lock);
                try
                {
                    byte[] buffer = (byte[])Array.CreateInstance(typeof(byte), encoder.GetByteCount(PassPhrase));
                    byte[] reverseBuffer = (byte[])Array.CreateInstance(typeof(byte), encoder.GetByteCount(PassPhrase));
                    buffer = encoder.GetBytes(PassPhrase);
                    for (Int32 i = 0; i <= buffer.Length - 1; i++)
                    {
                        reverseBuffer[i] = buffer[buffer.Length - i - 1];
                    }
                    return getDigest(reverseBuffer, 16);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] getDigest(string value, Encoding encoder, Int32 digestLength)
            {
                Monitor.Enter(_lock);
                try
                {
                    return getDigest(encoder.GetBytes(value), digestLength);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] getDigest(object value, Int32 digestLength)
            {
                Monitor.Enter(_lock);
                try
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    MemoryStream ms = new MemoryStream();
                    bf.Serialize(ms, value);
                    return getDigest(ms.ToArray(), digestLength);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] getDigest(byte[] value, Int32 digestLength)
            {
                Monitor.Enter(_lock);
                try
                {
                    Int32 iterations = 0;
                    // Find first non-zero byte value to use to calculate iterations
                    for (Int32 i = 0; i < value.Length; i++)
                    {
                        if (value[i] != 0) { iterations = (Int32)(value[i] * 10); break; }
                    }
                    // There were no non-zero byte values use the max for iterations
                    if (iterations == 0) { iterations = (Int32)(byte.MaxValue * 10); }
                    Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(value, new SHA256Managed().ComputeHash(value), iterations);
                    return deriveBytes.GetBytes(digestLength);
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
            #endregion
    
            #region HexArray/String String/HexArray Converters
            public static string ByteArrayToHexString(byte[] ba)
            {
                try
                {
                    Monitor.Enter(_lock);
                    StringBuilder hex = new StringBuilder(ba.Length * 2);
                    foreach (byte b in ba)
                        hex.AppendFormat("{0:x2}", b);
                    return hex.ToString();
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
    
            public static byte[] HexStringToByteArray(String hex)
            {
                try
                {
                    Monitor.Enter(_lock);
                    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;
                }
                finally
                {
                    Monitor.Exit(_lock);
                }
            }
            #endregion
        }
    }
    
    将结果base64编码字符串从encryptString保存到配置文件

    要恢复OEM密码,请执行以下操作:

    string encryptedPassword = "This is the base64 encoded string you read from your config file";
    string decrytptedPassword = Simple.AES256Encryption.decryptString(encryptedPassword, fileName, new UTF8Encoding(), stringIOType.base64EncodedString, new UTF8Encoding());
    

    如果是硬编码的,则将其存储在文件中不会被视为“硬编码”.:-|请先阅读问题,然后再发表评论。我不是将密码存储在xml中,而是将密码存储在我的代码中,以便能够解密文件。您本可以为我提供更好的解决方案,而不是完全讽刺。@phoog任何人都不应该被“密码”一词所迷惑我相信即使在非英语国家,它也能被很好地使用和理解。在现实生活中,“密码”=“密钥”=“密码短语”每个人都知道这一点。也许在教科书中它们是不同的,但现实生活才是重要的。把它变成术语争论解决不了任何问题,这是浪费时间。@RedSerpent我不是想把任何东西变成术语争论;我是想为人们为什么会误读你的问题提出一个可能的解释
    string encryptedPassword = "This is the base64 encoded string you read from your config file";
    string decrytptedPassword = Simple.AES256Encryption.decryptString(encryptedPassword, fileName, new UTF8Encoding(), stringIOType.base64EncodedString, new UTF8Encoding());