如何在 .NET 5.0 appsettings.json 文件中正确存储和访问加密值?
How to properly store and access encrypted values in .NET 5.0 appsettings.json file?
我需要能够将敏感数据存储在 .NET 5.0 应用程序的 appsettings.json 配置文件中。我一直在为 .NET Framework 应用程序使用配置文件的 RSA 加密,但我正在转向 .NET 5.0 应用程序开发,我想要一种比旧的 reg_iis.exe 方法更简单的 storing/accessing 秘密方法。
我已经尝试了一种方法,并且非常接近于让它起作用,但也许有更好的方法。我的做法:
- 在我的 appsettings.json 文件中设置加密值。这些加密值通过以下 PowerShell 脚本生成,然后复制到 .json 文件:
$SecureString = Read-Host "Enter the String to Encrypt" -AsSecureString
$EncryptedString = ConvertFrom-SecureString -SecureString $SecureString
$EncryptedString
- .NET 5.0 应用程序中用于解密字符串的扩展方法:
public static string Decrypt(this string str)
{
int length = str.Length / 2;
byte[] encryptedData = new byte[length];
for (int index = 0; index < length; ++index)
{
encryptedData[index] = byte.Parse(str.Substring(2 * index, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
// Decrypt the byte array to Unicode byte array
byte[] data = ProtectedData.Unprotect(encryptedData, null, DataProtectionScope.CurrentUser);
// Convert Unicode byte array to string
return Encoding.Unicode.GetString(data);
}
- 这个扩展方法如果在应用程序中就可以工作,但是我将需要它用于许多应用程序。所以我将它构建到一个 Class 库中,这样我就可以为每个应用程序添加一个 .dll 引用。问题是它依赖于
System.Security.Cryptography.ProtectedData
class。 .NET 5.0 显然不支持开箱即用,而是可以通过 NuGet 包含的平台扩展。我已经这样做了,正如我所说,如果它直接在应用程序中它可以工作,但作为 class 库的一部分,它不会...如果我在中包含 class 库程序集引用一个应用程序,class 库构建良好,但有一个例外:
System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Security.Cryptography.ProtectedData, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.'
它没有将 ProtectedData .dll 部署到消费应用程序,我认为它应该...
所以,我这样做本质上是错误的,还是我接近了?
您 运行 缺少汇编错误,因为您直接引用了已编译的库。构建系统不知道它的依赖项(即 ProtectedData.dll),因此当您构建应用程序时它不会将它们包含在输出文件夹中。
当您改为将库作为项目引用时,构建系统可以通过读取项目文件找出库所依赖的所有内容,并将这些依赖项包含在输出文件夹中。
如果出于某种原因确实需要直接引用 DLL,则需要将其依赖项(通常是构建它的整个输出文件夹)复制到应用程序的目录中。
将它作为一个项目来引用要容易得多,除非有一些限制阻止它。如果不可能,将其作为 NuGet 包进行部署和引用是一种替代方法,可确保您自动获取所有依赖项,但这也有其自身的复杂性。
关于您尝试使用应用程序设置执行的操作,这是行不通的。
您调用的方法传递给 winapi CryptProtectData
和 CryptUnprotectData
方法。他们使用从您的登录凭据派生的密钥,因此在一台机器上加密的数据不可能被另一台机器(甚至同一台机器上的另一个用户)解密。
您可以在此处阅读有关存储敏感信息的替代方法:https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-6.0&tabs=windows
我需要能够将敏感数据存储在 .NET 5.0 应用程序的 appsettings.json 配置文件中。我一直在为 .NET Framework 应用程序使用配置文件的 RSA 加密,但我正在转向 .NET 5.0 应用程序开发,我想要一种比旧的 reg_iis.exe 方法更简单的 storing/accessing 秘密方法。
我已经尝试了一种方法,并且非常接近于让它起作用,但也许有更好的方法。我的做法:
- 在我的 appsettings.json 文件中设置加密值。这些加密值通过以下 PowerShell 脚本生成,然后复制到 .json 文件:
$SecureString = Read-Host "Enter the String to Encrypt" -AsSecureString
$EncryptedString = ConvertFrom-SecureString -SecureString $SecureString
$EncryptedString
- .NET 5.0 应用程序中用于解密字符串的扩展方法:
public static string Decrypt(this string str)
{
int length = str.Length / 2;
byte[] encryptedData = new byte[length];
for (int index = 0; index < length; ++index)
{
encryptedData[index] = byte.Parse(str.Substring(2 * index, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
// Decrypt the byte array to Unicode byte array
byte[] data = ProtectedData.Unprotect(encryptedData, null, DataProtectionScope.CurrentUser);
// Convert Unicode byte array to string
return Encoding.Unicode.GetString(data);
}
- 这个扩展方法如果在应用程序中就可以工作,但是我将需要它用于许多应用程序。所以我将它构建到一个 Class 库中,这样我就可以为每个应用程序添加一个 .dll 引用。问题是它依赖于
System.Security.Cryptography.ProtectedData
class。 .NET 5.0 显然不支持开箱即用,而是可以通过 NuGet 包含的平台扩展。我已经这样做了,正如我所说,如果它直接在应用程序中它可以工作,但作为 class 库的一部分,它不会...如果我在中包含 class 库程序集引用一个应用程序,class 库构建良好,但有一个例外:
System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Security.Cryptography.ProtectedData, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.'
它没有将 ProtectedData .dll 部署到消费应用程序,我认为它应该...
所以,我这样做本质上是错误的,还是我接近了?
您 运行 缺少汇编错误,因为您直接引用了已编译的库。构建系统不知道它的依赖项(即 ProtectedData.dll),因此当您构建应用程序时它不会将它们包含在输出文件夹中。
当您改为将库作为项目引用时,构建系统可以通过读取项目文件找出库所依赖的所有内容,并将这些依赖项包含在输出文件夹中。
如果出于某种原因确实需要直接引用 DLL,则需要将其依赖项(通常是构建它的整个输出文件夹)复制到应用程序的目录中。
将它作为一个项目来引用要容易得多,除非有一些限制阻止它。如果不可能,将其作为 NuGet 包进行部署和引用是一种替代方法,可确保您自动获取所有依赖项,但这也有其自身的复杂性。
关于您尝试使用应用程序设置执行的操作,这是行不通的。
您调用的方法传递给 winapi CryptProtectData
和 CryptUnprotectData
方法。他们使用从您的登录凭据派生的密钥,因此在一台机器上加密的数据不可能被另一台机器(甚至同一台机器上的另一个用户)解密。
您可以在此处阅读有关存储敏感信息的替代方法:https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-6.0&tabs=windows