为什么不使用 DPAPI 来加密所有设置而不是仅加密主密码?

Joh*_*aps 5 c# encryption dpapi

在我的应用程序中,我需要加密各种设置和密码。\n到目前为止,我一直在使用 RijndaelManaged 类等执行此操作,如下所示:

\n\n
/// <summary>\n/// Encrypts the string defined by parameter "data" and returns the encrypted data as string\n/// </summary>\n/// <param name="data">Data to be encrypted</param>\n/// <returns>The encrypted data</returns>\npublic static string Encrypt(string data)\n        {\n            if (data == "")\n                return "";\n\n            byte[] bytes = Encoding.ASCII.GetBytes(initVector);\n            byte[] rgbSalt = Encoding.ASCII.GetBytes(saltValue);\n            byte[] buffer = Encoding.UTF8.GetBytes(data);\n            byte[] rgbKey = new PasswordDeriveBytes(passPhrase, rgbSalt, hashAlgorithm, passwordIterations).GetBytes(keySize / 8);\n            RijndaelManaged managed = new RijndaelManaged();\n            managed.Mode = CipherMode.CBC;\n            ICryptoTransform transform = managed.CreateEncryptor(rgbKey, bytes);\n            MemoryStream memStream = new MemoryStream();\n            CryptoStream cryStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);\n            cryStream.Write(buffer, 0, buffer.Length);\n            cryStream.FlushFinalBlock();\n            byte[] inArray = memStream.ToArray();\n            memStream.Close();\n            cryStream.Close();\n            return Convert.ToBase64String(inArray);\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

通常的问题是我需要将 passPhrase(和 saltValue)存储在某处。\n为了以连续的方式存储 passPhrase,我遇到了 DPAPI Protect() 和 Unprotect() 类,如下所示:

\n\n
/// <summary>\n/// Use Windows\' "Data Protection API" to encrypt the string defined by parameter "clearText".\n/// To decrypt, use the method "Unprotect"\n/// http://www.thomaslevesque.com/2013/05/21/an-easy-and-secure-way-to-store-a-password-using-data-protection-api/\n/// </summary>\n/// <param name="clearText"></param>\n/// <param name="optionalEntropy"></param>\n/// <param name="scope"></param>\n/// <returns></returns>\n        public static string Protect(string clearText, string optionalEntropy = null, DataProtectionScope scope = DataProtectionScope.CurrentUser)\n        {\n            if (clearText == null)\n                throw new ArgumentNullException("The parameter \\"clearText\\" was empty");\n            byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);\n            byte[] entropyBytes = string.IsNullOrEmpty(optionalEntropy) ? null : Encoding.UTF8.GetBytes(optionalEntropy);\n            byte[] encryptedBytes = ProtectedData.Protect(clearBytes, entropyBytes, scope);\n            return Convert.ToBase64String(encryptedBytes);\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的问题如下: \n使用 DPAPI,我现在可以以安全的方式存储加密方法的密码,但为什么\xe2\x80\x99t 我只需使用 DPAPI 直接加密我的所有设置?\n这会填充吗向 DPAPI 添加大量数据,但它不适合?

\n\n

我的想法是不执行以下操作:

\n\n
string setting1 = \xe2\x80\x9dmySettingValue1\xe2\x80\x9d;\nStoreSettingSomewhere(Encrypt(setting1));\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以执行以下操作:

\n\n
string setting1 = \xe2\x80\x9dmySettingValue1\xe2\x80\x9d;\nStoreSettingSomewhere(Protect(setting1, bla bla bla));\n
Run Code Online (Sandbox Code Playgroud)\n\n

我知道在使用 DPAPI 时我必须在同一台机器上(或使用同一用户)解密,但这对我来说不是问题。

\n\n

任何帮助表示赞赏!

\n

Ian*_*oyd 3

数据保护 API 会返回一个不透明的 blob,它是您想要加密的内容的加密(加盐和散列)结果。

您无法“填充” DP API - 您只能自己“填充”(因为 blob 有点大;但它们内部确实包含稍后验证加密数据所需的所有内容)。

数据保护 API 的缺点是您必须以用户身份登录;并且您无法在用户之间共享设置(除非您使用计算机范围)。

  • 好,我知道了。所以 DPAPI 实际上有点像我自己的加密类。谢谢你隔了这么久才回复! (2认同)