C#确保数据来自第三方,而数据没有';t已更改

本文关键字:数据 确保 第三方 | 更新日期: 2023-09-27 18:26:31

我正试图在服务器上写一个简单的版本数据检查。结果将是一个JSON响应,其中包含当前版本#,无论该版本是否需要更新程序才能继续运行,以及一些带有新版本功能列表的HTML数据。

我想做的是以一种最终用户无法伪造的安全方式将这些数据从我的Web服务器发送到我的C#应用程序。

我最初考虑在服务器端使用RSA用私钥对其进行加密,并在客户端使用公钥对其进行解码,但显然RSA(至少是本机.NET RSA)无法处理这种情况,因为它希望使用私钥进行解码。

我正在寻找关于如何做到这一点的任何提示或建议。我确实看到RSA有一个verifyhash或verifydata方法,但我似乎找不到任何关于如何安全地做到这一点的好例子。。如果您只是发送一个散列,那么使用RSA有什么意义?如果客户端是.NET,他们可以很容易地解码哈希是如何创建的,并自己伪造它。。。

我也在寻找一个.NET(3.5)解决方案,因为该应用程序目前是独立的,我不想添加依赖项。

我不是在寻找任何代码,只是一些对谷歌有用的主题或其他什么,因为我一直在搜索的并没有返回任何看起来有用的东西。

谢谢,

Smitty

编辑以添加我发现的一些链接,这些链接表示您无法使用公钥进行解码

解码OAEP填充时出错

C#RSA加密/解密抛出异常

C#确保数据来自第三方,而数据没有';t已更改

您发布的第一个链接中接受的答案并不完全正确。.NET框架确实支持此操作,但名称不同。

在像RSA这样的非对称密码系统中,可以通过用私钥"加密"和用公钥"解密"来建立不可否认性。因为这种加密操作旨在防止篡改,而不是为了保密,所以它被称为(在框架API中被称为)数据签名,而不是加密。

正确的使用方法是,如您所建议的,SignData/SignHash使用私钥对数据进行签名,VerifyData/VerifyHash使用公钥验证数据。

使用私钥加密所涉及的数学运算对可以签名的数据的大小进行了实际限制。因此,通常使用加密散列(例如,SHA1)对正在签名的数据进行散列,然后对该散列进行签名。.NET框架API强制执行此限制。

作为一个简单的示例,您可以使用以下代码在服务器上对数据进行签名。

public byte[] SignData(RSAParameters privateParameters, byte[] data)
    {
        using (var csp = new RSACryptoServiceProvider())
        using (var sha1 = new SHA1CryptoServiceProvider())
        {
            csp.ImportParameters(privateParameters);
            return csp.SignData(data, sha1);
        }
    }

客户端可以通过提供(a)公共RSA参数、(b)签名和(c)原始数据来验证数据是否使用私钥签名。此外,客户端必须知道用于生成签名的哈希算法:

public bool VerifySignature(RSAParameters publicParameters, byte[] data, byte[] signature)
{
    using (var csp = new RSACryptoServiceProvider())
    using (var sha1 = new SHA1CryptoServiceProvider())
    {
        csp.ImportParameters(publicParameters);
        return csp.VerifyData(data, sha1, signature);
    }
}

如果签名或数据被篡改,您可以测试VerifySignature是否返回false。

最后,您写道,目的是提供"最终用户无法欺骗的安全方式"。有了数字签名,用户可以对提供给它的数据来自有效来源有很高的信心。它不能防止最终用户串通一气的攻击,例如导致绕过检查或用最终用户控制的公钥替换公钥。