C#确保数据来自第三方,且数据没有#x27;不改变

C#确保数据来自第三方,且数据没有#x27;不改变,c#,encryption,hash,C#,Encryption,Hash,我正试图在我的服务器上写一个简单的版本数据检查。结果将是一个JSON响应,其中包含当前版本#,该版本是否需要更新以使程序保持正常运行,以及新版本的一些带有功能列表的HTML数据 我试图做的是以最终用户无法欺骗的安全方式将这些数据从我的Web服务器发送到我的C#应用程序 我最初考虑使用RSA在服务器端使用私钥对其进行加密,并在客户端使用公钥对其进行解码,但显然RSA(至少本机.NET RSA)无法处理这种情况,因为它希望使用私钥进行解码 我正在寻找关于如何做到这一点的任何提示或建议。我确实看到RS

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

我试图做的是以最终用户无法欺骗的安全方式将这些数据从我的Web服务器发送到我的C#应用程序

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

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

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

我不是在寻找任何代码,只是一些对谷歌有用的主题,因为我一直在搜索的东西并没有返回任何似乎有用的东西

谢谢

斯密蒂

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


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

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

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

使用私钥加密所涉及的数学运算对可签名数据的大小有实际限制。因此,通常使用加密散列(例如,SHA1)对正在签名的数据进行散列,然后对散列进行签名。.NET framework 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


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

我对加密了解不多,几乎一无所知,但我发现很难相信.Net RSA实现不允许使用公钥解密。这就是RSA背后的全部想法。我也是这么想的,但我发现的一切都表明它不是为了这个目的。它意味着用公钥加密,用私钥解码。我正试图找到上面提到的链接,当我找到时,我会修改我的问题,将它们包括在内。嗯,是的,我确实展示了我对加密的缺乏知识。好的,你可以不加密地将信息从服务器发送到客户端,客户端认为它可能是可疑的。客户端对信息加上一个随机数进行散列,然后向服务器发送一条加密消息(公钥加密),说“你真的是你声称的那个人吗?”然后服务器以明文回答,“是的,你可以相信我,你的散列是正确的,你的随机数是x!”这实际上是一种非常巧妙的处理方式,但是,这确实意味着对服务器的第二次调用。。。这很可能不是什么问题。。。。嗯,我很想看看其他人怎么想,如果在这种情况下有一个最佳实践,但你的解决方案肯定解决了我的问题,所以我感谢你!感谢您对签署和验证数据的解释。您的代码基本上就是我以前尝试过的,但它没有验证数据,并且总是返回false。在你的解释下,我向前推进,并最终确定了我的公钥导入错误的问题。再次感谢!