使用RijndaelManaged从ASP.NET成员资格中解密加密密码

The*_*yan 2 c# encryption asp.net-membership class-library

底线是创建自定义FTP身份验证提供程序.为了做到这一点,必须从IFtpAuthenticationProvider接口继承,然后在GAC中注册该程序集.之后,需要在IIS的FTP设置中注册程序集.

为了实现这一目标,我必须使用数据库,该数据库将我的用户信息保存在我们之前开发的自定义成员资格和角色提供程序的数据库中.所以,这意味着我必须使用本地类库app.config文件并阅读它ConfigurationManager.OpenMappedExeConfiguration().我从那里读取连接字符串,我甚至能够动态地它提供给Linq-To-Sql类.没问题.

接下来,我尝试创建一个继承自SqlMembershipProvider的类,以便我可以使用它自己的系统来解密用户的密码.但是,问题是它必须machineKey从配置中读取值.您可以为SqlMembershipProvider提供自定义配置的唯一方法是使用它的Initialize方法(无论如何我们都不打算在我们的代码中使用它).但无论如何我试过并失败了.我已经能够提供自定义成员资格设置,但不能提供machineKey设置.

所以,我决定变得激进.我说:我有decryptionKey来自machineKey所以我会尝试手动解密密码.

到目前为止,我已尝试使用RijndaelManaged:

    private string UnEncodePassword(string encodedPassword, string secretKey)
    {
        string password = encodedPassword;

        var keyBytes = new byte[16];
        var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
        Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));

        RijndaelManaged rm = new RijndaelManaged
        {
            Mode = CipherMode.CBC,
            Padding = PaddingMode.PKCS7,
            KeySize = 128,
            BlockSize = 128,
            Key = keyBytes,
            IV = keyBytes
        };

        var encryptedBytes = Convert.FromBase64String(encodedPassword);
        password = Encoding.UTF8.GetString(Decrypt(encryptedBytes, rm));

        return password;
    }
Run Code Online (Sandbox Code Playgroud)

我有点意识到我在这里拍摄空白,因为我不确定使用什么样的填充,最重要的是,即使我不能击中正确的IV.到目前为止,我做的最好的事情是得到一些垃圾回应,如: 21l < ( \t ).

所以我需要一些指示.甚至关于如何从另一个角度处理整个问题的建议也是值得欢迎的.

编辑:

只是为了让事情变得更加清晰.我不是想破解密码或任何东西.我有密码,我有decryptionKey等.我只是想找到一种方法来加密/解密它,以便我可以进行用户验证.
我充分意识到加密/解密密码并不是最好的方法,但有理由说明为什么会这样做.

Chr*_*sic 5

你不应该解密密码.你应该比较密码哈希值.

密码不应与可逆加密一起存储.密码意味着存储为哈希(不是MD5,它太弱).

关于上面的评论,您不需要解密密码来比较它们.您想要比较哈希值,而不是原始值.系统不应该能够获得密码的原始文本.使用内置的ASP.NET成员资格提供程序正确地将密码存储为哈希.这可能是你不能解密它们的原因,它们是无法解密的.

编辑:关于您passwordFormat="Encrypted"用于SQL成员资格提供程序的事实.有了这个事实,您可以使用相同的格式加密密码,使用相同的填充,cipherMode和IV(您需要从SQL数据库中查询),然后只比较加密的密码值.这可能是不必要的工作.您真的只想在代码中使用用户名/密码组合调用Membership的登录功能,并验证它是否成功.您需要确保机器钥匙和相关部件在两个系统中都匹配,否则您将无法成功.

你真的想要计划转移到散列密码,但是存储加密密码而不是散列密码几乎没有意义.它只比将它们以纯文本形式存储稍微好一些.