我的 Web api 如何使用 DPAPI 解密之前在控制台应用程序中加密的密码?

问题描述 投票:0回答:1

我必须将用户凭据存储在某个 Web API 中。我决定在解决方案中的 Web API 旁边创建一个控制台应用程序,用于加密数据,并将其写入 Web API 的 appsettings.json。
这是相关代码:

var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection(o =>
{
    o.ApplicationDiscriminator = CoreVariables.SALT;
}
).SetApplicationName("test");

var services = serviceCollection.BuildServiceProvider();

var dataProtector = services.GetRequiredService<IDataProtectionProvider>();
var protector = dataProtector.CreateProtector(CoreVariables.DATA_PROTECTION_REASON);

//Fill username and password, REMOVE AFTER ENCRYPTION, DONT PUSH IT TO REPOSITORY
string username = "";
string password = "";

if (string.IsNullOrEmpty(username))
{
    throw new Exception("Username cannot be null or empty.");
}

if (string.IsNullOrEmpty(password))
{
    throw new Exception("Username cannot be null or empty.");
}

string protectedUsername = protector.Protect(username);
string protectedPassword = protector.Protect(password);

string appsettingsFilePath =
    Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.FullName,
        "My.API", "appsettings.json");

if (!File.Exists(appsettingsFilePath))
{
    throw new Exception($"Cannot find file in path: {appsettingsFilePath}");
}

var appsettingsContent = File.ReadAllText(appsettingsFilePath);
var appsettingsJson = JsonConvert.DeserializeObject<Dictionary<string, object>>(appsettingsContent);
appsettingsJson["User"] = protectedUsername;
appsettingsJson["Secret"] = protectedPassword;
appsettingsJson["SecretLastChanged"] = DateTime.Now.ToString();
var updatedJson = JsonConvert.SerializeObject(appsettingsJson, Formatting.Indented);
File.WriteAllText(appsettingsFilePath, updatedJson);

然后,当我部署应用程序时,出现异常,提示 在密钥环中找不到密钥。

以下是 API 中的相关代码:

程序.cs:

builder.Services.AddDataProtection(o => {
        o.ApplicationDiscriminator = CoreVariables.SALT;
        
    }
).SetApplicationName("test");

服务,我使用它的地方:

 public MyService(IDataProtectionProvider provider)
 {
     _protector = provider.CreateProtector(CoreVariables.DATA_PROTECTION_REASON);
 }

 public async Task<string> Authentication(string userName, string password)
 {
     string authUsername = _protector.Unprotect(userName);
     string authPassword = _protector.Unprotect(password);
 }

这种加密是否以某种方式与计算机数据相关?当我将应用程序部署到服务器中时,解密将不起作用。

asp.net-core encryption .net-6.0 dpapi
1个回答
0
投票

密钥默认保存在电脑系统目录下。您可以添加以下配置来指定密钥文件路径。 (xxxx.xml)

serviceCollection.AddDataProtection(o =>
{
    o.ApplicationDiscriminator = CoreVariables.SALT;
}
).SetApplicationName("test").PersistKeysToFileSystem(new DirectoryInfo(Environment.CurrentDirectory));

然后运行控制台应用程序时,您会发现该路径下生成了一个密钥文件。它包含了关键信息。
enter image description here
enter image description here

但是每次运行控制台应用程序时。它将生成一个新密钥(也是一个新的 xxx.xml 文件)以供使用。所以当你有了这个文件之后。我们可以禁用生成新密钥以使其始终使用旧密钥:

...
SetApplicationName("test").PersistKeysToFileSystem(new DirectoryInfo(Environment.CurrentDirectory))
.DisableAutomaticKeyGeneration();

然后您可以将此文件复制到“api计算机”并使用相同的设置来指定使用此密钥文件。 (也禁用密钥生成)

© www.soinside.com 2019 - 2024. All rights reserved.