我必须将用户凭据存储在某个 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);
}
这种加密是否以某种方式与计算机数据相关?当我将应用程序部署到服务器中时,解密将不起作用。
密钥默认保存在电脑系统目录下。您可以添加以下配置来指定密钥文件路径。 (xxxx.xml)
serviceCollection.AddDataProtection(o =>
{
o.ApplicationDiscriminator = CoreVariables.SALT;
}
).SetApplicationName("test").PersistKeysToFileSystem(new DirectoryInfo(Environment.CurrentDirectory));
然后运行控制台应用程序时,您会发现该路径下生成了一个密钥文件。它包含了关键信息。
但是每次运行控制台应用程序时。它将生成一个新密钥(也是一个新的 xxx.xml 文件)以供使用。所以当你有了这个文件之后。我们可以禁用生成新密钥以使其始终使用旧密钥:
...
SetApplicationName("test").PersistKeysToFileSystem(new DirectoryInfo(Environment.CurrentDirectory))
.DisableAutomaticKeyGeneration();
然后您可以将此文件复制到“api计算机”并使用相同的设置来指定使用此密钥文件。 (也禁用密钥生成)