我正在尝试创建一个静态类和方法来加密和解密asp.net核心中的数据。
但是问题是我必须在带有DI的构造函数中获取“ IDataProtectionProvider提供程序”,然后将其传递给方法,以便使用CreateProtector。
我不想要那样,而是直接想通过自己的方法实例化IDataProtectionProvider提供程序。
控制器代码:
private readonly IDataProtectionProvider _provider;
public addMDL(IDataProtectionProvider provider)
{
_provider = provider;
}
public IActionResult OnGet()
{
DataProProvider.decData(0, "ABC", _provider)
}
,静态类是:
public static class DataProProvider
{
public static string encData(int intData, string strData, IDataProtectionProvider provider)
{
string str;
IDataProtector dataProtector;
dataProtector = provider.CreateProtector("AA");
if (!string.IsNullOrEmpty(strData))
{
str = dataProtector.Protect(strData);
}
else
{
str = dataProtector.Protect(intData.ToString());
}
return str;
}
public static string decData(int intData, string strData, IDataProtectionProvider provider)
{
string str;
IDataProtector dataProtector;
dataProtector = provider.CreateProtector("A3");
if (!string.IsNullOrEmpty(strData))
{
str = dataProtector.Unprotect(strData);
}
else
{
str = dataProtector.Unprotect(intData.ToString());
}
return str;
}
}
[更新]
根据建议,我已使用Encrypting & Decrypting a String in C# enter link description here
答案 0 :(得分:2)
浏览源代码,似乎只有通过一些反射黑客或代码复制才能实现不带DI的 IDataProtectionProvider 实例化。
看看this code,您可以看到在DI容器中为各种接口注册了哪些实现。例如。 IDataProtectionProvider 的实现是 KeyRingBasedDataProtectionProvider 。现在查看source of that class。它是内部的,因此您不能在声明程序集之外实例化它(无反射)。经过进一步的挖掘,事实证明提供程序也创建了KeyRingBasedDataProtector实例,这些实例也声明为内部实例。
所有这些都表明DataProtection API不能在没有DI容器的情况下使用。您应该重新考虑您真的想以这种方式使用它。
答案 1 :(得分:0)
您可以参考Microsoft关于如何将Data Protection用于非DI解决方案(https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/non-di-scenarios?view=aspnetcore-2.2)的建议。
简而言之,请使用静态方法DataProtectionProvider.Create()
:
using Microsoft.AspNetCore.DataProtection;
static class Program
{
static void Main()
{
var dataProtectionProvider = DataProtectionProvider.Create("Test App");
var protector = dataProtectionProvider.CreateProtector("Program.No-DI");
var plainText = "ABCDEFGH";
var protectedText = protector.Protect(plainText);
}
}
答案 2 :(得分:0)
由于在幕后实现,无法避免使用 DI。如果您查看“非 DI 示例”DataProtectionProvider.Create(...)
,您会发现他们使用专用的组合根来提供保护器。
受此启发我写了这个方法:
private static IDataProtectionProvider CreateDataProtectionProviderWithPostgresKeyRepository(string connectionString)
{
var services = new ServiceCollection();
var builder = services.AddDataProtection();
builder.Services.AddSingleton<IConfigureOptions<KeyManagementOptions>>(sp =>
{
return new ConfigureOptions<KeyManagementOptions>(options =>
{
options.XmlRepository = new PostgresDataProtectionKeyRepository(connectionString);
});
});
return services.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>();
}
其中 PostgresDataProtectionKeyRepository
只是用于将密钥存储在数据库中的 IXmlRepository
的愚蠢 implementation。