C# .NET DPAPI和AES加密:检测
我正准备为我目前正在开发的一个网站编写一个新的加密系统,如果可能的话,我想看看是否能在我开始之前让人对它进行检测 更新:我的原始问题应该更清楚。我需要加密一些用户数据,我还需要能够在以后的数据存储中读取这些数据。而且,我还需要存储用户密码或密码哈希,以便在登录时验证用户。 该计划是:C# .NET DPAPI和AES加密:检测,c#,.net,encryption,aes,dpapi,C#,.net,Encryption,Aes,Dpapi,我正准备为我目前正在开发的一个网站编写一个新的加密系统,如果可能的话,我想看看是否能在我开始之前让人对它进行检测 更新:我的原始问题应该更清楚。我需要加密一些用户数据,我还需要能够在以后的数据存储中读取这些数据。而且,我还需要存储用户密码或密码哈希,以便在登录时验证用户。 该计划是: 主密钥:创建一个DPAPI密钥设置程序应用程序,以获取基于文本的主密钥,通过DPAPI进行加密,然后将加密输出保存到服务器上的文本文件中。这是一项一次性任务,每次将站点移动到新服务器时,我都将执行该任务。主密钥将用
我是新来的,以前曾在这类东西上使用过企业库安全性(在.NETCore中不再可用!),所以非常感谢您的帮助 如果可以避免,则永远不要存储密码 我不清楚第1步中的密码是什么。如果新用户直到第2步才出现,这是谁的密码 无论如何,对于用户来说,更好的计划是使用/保存衍生材料。例如,在新用户注册时,执行以下操作
byte[] exportBytes;
byte[] exportSalt;
int exportPasswordSettingsVersion = YourSystemConfiguration.NewPasswordSettingsVersion;
using (Rfc2898DeriveBytes registerer = new Rfc2898DeriveBytes(
newUserPassword,
YourSystemConfiguration.GetSaltSize(exportPasswordSettingsVersion),
YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion)))
{
exportSalt = registerer.Salt;
exportBytes = registerer.GetBytes(
YourSystemConfiguration.GetDerivedKeySize(exportPasswordSettingsVersion));
}
然后导出salt字节(为您随机生成)、派生密码字节和sett作为用户配置文件的一部分。当用户登录时,您将加载这些值并检查它们是否匹配:
using (Rfc2898DeriveBytes verifier = new Rfc2898DeriveBytes(
inputPassword,
loadedProfile.Salt,
YourSystemConfiguration.GetIterationCount(loadedProfile.PasswordSettingsVersion)))
{
byte[] verifyBytes = registerer.GetBytes(loadedProfile.PasswordVerify.Length);
if (!ConstantTimeEquals(verifyBytes, loadedProfile.PasswordVerify))
{
return false;
}
if (loadedProfile.PasswordSettingsVersion < YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion))
{
// Re-derive their password and save it with your newer (stronger, presumably) cryptographic settings.
}
return true;
}
使用(Rfc2898DeriveBytes)验证器=新的Rfc2898DeriveBytes(
输入密码,
装载的档案。盐,
YourSystemConfiguration.GetIterationCount(loadedProfile.PasswordSettingsVersion)))
{
byte[]verifyBytes=registerer.GetBytes(loadedProfile.PasswordVerify.Length);
if(!ConstantTimeEquals(verifyBytes,loadedProfile.PasswordVerify))
{
返回false;
}
if(loadedProfile.passwordsetingsversion
这项计划:
- 使用RFC2898的PBKDF2算法从密码中派生密钥,存储此派生值比存储密码要好,因为如果您的凭据数据库受损,它不会泄露密码
- 为每个新用户使用新的随机盐。(也可以在更改密码或升级登录时重新生成)
- 保存(并加载)有关设置密码时使用的设置的信息,以便将来更改默认设置
- 不使用DPAPI(DPAPI不错,但它仅适用于Windows,如果您使用的是.NET Core,则可能需要跨平台解决方案)
byte[] exportBytes;
byte[] exportSalt;
int exportPasswordSettingsVersion = YourSystemConfiguration.NewPasswordSettingsVersion;
using (Rfc2898DeriveBytes registerer = new Rfc2898DeriveBytes(
newUserPassword,
YourSystemConfiguration.GetSaltSize(exportPasswordSettingsVersion),
YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion)))
{
exportSalt = registerer.Salt;
exportBytes = registerer.GetBytes(
YourSystemConfiguration.GetDerivedKeySize(exportPasswordSettingsVersion));
}
然后导出salt字节(为您随机生成)、派生密码字节和sett作为用户配置文件的一部分。当用户登录时,您将加载这些值并检查它们是否匹配:
using (Rfc2898DeriveBytes verifier = new Rfc2898DeriveBytes(
inputPassword,
loadedProfile.Salt,
YourSystemConfiguration.GetIterationCount(loadedProfile.PasswordSettingsVersion)))
{
byte[] verifyBytes = registerer.GetBytes(loadedProfile.PasswordVerify.Length);
if (!ConstantTimeEquals(verifyBytes, loadedProfile.PasswordVerify))
{
return false;
}
if (loadedProfile.PasswordSettingsVersion < YourSystemConfiguration.GetIterationCount(exportPasswordSettingsVersion))
{
// Re-derive their password and save it with your newer (stronger, presumably) cryptographic settings.
}
return true;
}
使用(Rfc2898DeriveBytes)验证器=新的Rfc2898DeriveBytes(
输入密码,
装载的档案。盐,
YourSystemConfiguration.GetIterationCount(loadedProfile.PasswordSettingsVersion)))
{
byte[]verifyBytes=registerer.GetBytes(loadedProfile.PasswordVerify.Length);
if(!ConstantTimeEquals(verifyBytes,loadedProfile.PasswordVerify))
{
返回false;
}
if(loadedProfile.PasswordSettingsVersion
这项计划:
- 使用RFC2898的PBKDF2算法从密码中派生密钥,存储此派生值比存储密码要好,因为如果您的凭据数据库受损,它不会泄露密码
- 为每个新用户使用新的随机盐。(也可以在更改密码或升级登录时重新生成)
- 保存(并加载)有关设置密码时使用的设置的信息,以便将来更改默认设置
- 不使用DPAPI(DPAPI不错,但它仅适用于Windows,如果您使用的是.NET Core,则可能需要跨平台解决方案)
- 忽略密码问题,仅考虑用户数据,您的方案很好,但可以改进
基本上,您有一个主密钥——一个对称密钥,或者16或32字节,它在静止状态下(在磁盘上)受到保护,您可以在服务器的内存中解密它
用户数据使用主密钥加密,并带有随机IV fo