用于查询字符串保护的 MS 数据保护 API 对给定的明文强制使用相同的密文

MS Data Protection API for Query String Protection force same ciphertext for given plaintext

提问人:Twe2 提问时间:9/23/2021 更新时间:9/23/2021 访问量:162

问:

我正在使用数据保护 API 通过加密查询字符串中的值来保护我的 MVC .NET Core 2.2 Web 应用程序免受 IDOR(不安全的直接对象引用)bug 的侵害。

我有以下基于此处的 Microsoft 文档的代码,用于说明我的问题。

当我两次输入相同的输入时,我会得到不同的密文。我想知道是否可以使用数据保护 API 输出相同的密文,因为在我的 Web 应用程序中,我在后端的两个不同位置调用了 Protect 方法,然后我希望加密值在 UI 上相同。

using System;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;

public class ConsoleApp1
{
    public static void Main(string[] args)
    {
        // add data protection services
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddDataProtection();
        var services = serviceCollection.BuildServiceProvider();

        // create an instance of MyClass using the service provider
        var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
        instance.RunSample();
    }

    public class MyClass
    {
        IDataProtector _protector;

        // the 'provider' parameter is provided by DI
        public MyClass(IDataProtectionProvider provider)
        {
            _protector = provider.CreateProtector("Contoso.MyClass.v1");
        }

        public void RunSample()
        {
            Console.Write("Enter input: ");
            string input;
            while ((input = Console.ReadLine()) != "xx")
            {
                // protect the payload
                string protectedPayload = _protector.Protect(input);
                Console.WriteLine($"Protect returned: {protectedPayload}");

                // unprotect the payload
                string unprotectedPayload = _protector.Unprotect(protectedPayload);
                Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
            } 
        }
    }
}

/*
 * SAMPLE OUTPUT
 *
 * Enter input: Hello world!
 * Protect returned: CfDJ8ICcgQwZZhlAlTZT...OdfH66i1PnGmpCR5e441xQ
 * Unprotect returned: Hello world!
 */

我的输出

1
Protect returned: CfDJ8Pj60RReYshEqBeXl2Zl8luwN5Aj4EPgXaSWPinkIFxn3jnRhTFT8cBsZTasBeWeLGwhVJ9g7y6i2KgUFboawqZf-SlkkTl1X3hlmr3Qnnaiuwh3JBIS_cGAvPO7bLLdlg
Unprotect returned: 1

1
Protect returned: CfDJ8Pj60RReYshEqBeXl2Zl8luMYV9VXpAZwn9-6gzprRoC0GHCc_XTmeHs2Ln-DZByY9AzJAOvvrupwPTB9xLXYKj8W7xsDEA4hMxpwCQXuYhTZ-Rs4Kt6D69ldlmMbAHnAw
Unprotect returned: 1
C# ASP.NET-MVC 安全性 DPAPI

评论

0赞 ste-fu 9/23/2021
我怀疑。将相同的明文加密为相同的密文可能会导致加密减弱。简单的方法,如旨在阻止犯这种错误Protect

答:

0赞 ste-fu 9/23/2021 #1

我不确定加密查询字符串是否真的会阻止不安全的直接对象引用。如果有人要拦截该 URL 或确实直接与其他用户共享该 URL,那么他们仍然可以访问该记录。

为了正确安全,您需要实现某种身份验证。如果你真的不想实现这一点,那么使用 a 作为 id 而不是 an 会给你一个难以猜测的参数,但它仍然容易受到拦截或故意共享的影响Guidint