Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET DPAPI和AES加密:检测_C#_.net_Encryption_Aes_Dpapi - Fatal编程技术网

C# .NET DPAPI和AES加密:检测

C# .NET DPAPI和AES加密:检测,c#,.net,encryption,aes,dpapi,C#,.net,Encryption,Aes,Dpapi,我正准备为我目前正在开发的一个网站编写一个新的加密系统,如果可能的话,我想看看是否能在我开始之前让人对它进行检测 更新:我的原始问题应该更清楚。我需要加密一些用户数据,我还需要能够在以后的数据存储中读取这些数据。而且,我还需要存储用户密码或密码哈希,以便在登录时验证用户。 该计划是: 主密钥:创建一个DPAPI密钥设置程序应用程序,以获取基于文本的主密钥,通过DPAPI进行加密,然后将加密输出保存到服务器上的文本文件中。这是一项一次性任务,每次将站点移动到新服务器时,我都将执行该任务。主密钥将用

我正准备为我目前正在开发的一个网站编写一个新的加密系统,如果可能的话,我想看看是否能在我开始之前让人对它进行检测

更新:我的原始问题应该更清楚。我需要加密一些用户数据,我还需要能够在以后的数据存储中读取这些数据。而且,我还需要存储用户密码或密码哈希,以便在登录时验证用户。

该计划是:

  • 主密钥:创建一个DPAPI密钥设置程序应用程序,以获取基于文本的主密钥,通过DPAPI进行加密,然后将加密输出保存到服务器上的文本文件中。这是一项一次性任务,每次将站点移动到新服务器时,我都将执行该任务。主密钥将用于执行AES加密

  • 新用户注册时:

    2.1。保存密码数据/密码数据的哈希

    2.2。加载主密钥文件,使用DPAPI解密密钥。使用解密的主密钥,并对每段用户数据使用新的随机IV来创建AES加密字符串。通过在加密字符串前面加上相应的random IV来保存每个加密字符串,并插入数据库中的varchar列

  • 用户登录时:

    3.1。匹配密码哈希以验证用户

    3.2。对于每个加密的用户数据字段,将内容分为两部分:IV和加密数据。从DPAPI和IV获取主密钥,解密数据并显示在屏幕上

  • 听起来怎么样?上述内容是否存在明显缺陷


    我是新来的,以前曾在这类东西上使用过企业库安全性(在.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,则可能需要跨平台解决方案)

    如果可以避免,则永远不要存储密码

    我不清楚第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.PasswordSettingsVersion
    这项计划:

    • 使用RFC2898的PBKDF2算法从密码中派生密钥,存储此派生值比存储密码要好,因为如果您的凭据数据库受损,它不会泄露密码
    • 为每个新用户使用新的随机盐。(也可以在更改密码或升级登录时重新生成)
    • 保存(并加载)有关设置密码时使用的设置的信息,以便将来更改默认设置
    • 不使用DPAPI(DPAPI不错,但它仅适用于Windows,如果您使用的是.NET Core,则可能需要跨平台解决方案)

      • 忽略密码问题,仅考虑用户数据,您的方案很好,但可以改进

        基本上,您有一个主密钥——一个对称密钥,或者16或32字节,它在静止状态下(在磁盘上)受到保护,您可以在服务器的内存中解密它

        用户数据使用主密钥加密,并带有随机IV fo