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

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

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

我有以下基于 Microsoft 文档 here 的代码可以说明我的问题。

当我两次输入相同的输入时,我得到了不同的密文。我想知道是否可以使用数据保护 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

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

为了确保安全,您需要实施一些 sort of auth。如果你真的不想实现它,那么使用 Guid 作为 id 而不是 int 会给你一个难以猜测的参数,但它仍然容易受到拦截或故意共享