【问题标题】:C# RSA Encrypt Private Decrypt Public?C# RSA 加密私有解密公共?
【发布时间】:2011-06-18 20:58:42
【问题描述】:

这是我要解决的问题。假设我正在发布一些基于 ASP.NET MVC 构建的 Web 软件,我只希望最终用户能够将 X 用户添加到系统中。该软件将托管在他们的服务器上。

我想包含一个加密文件,当用户尝试添加新用户时,它会从文件中读取加密字符串。当网站对其进行解码时,明文将是允许的用户数。

最好/最简单的加密方式是什么?显然,我想确保最终用户不能旋转他们自己的加密字符串而只是替换我的。我不想担心必须尝试混淆我的源代码,这样他们就无法看到我是如何解码字符串的。

是否可以使用私有 rsa 密钥进行加密,然后使用公共密钥对其进行解密?我在下面的代码中没有运气:

        var rsa = new RSACryptoServiceProvider();

        var pubicKey = rsa.ToXmlString(false);
        var privateKey = rsa.ToXmlString(true);

        var test = "this string needs to be encrypted then decrypted";

        var rsa2 = new RSACryptoServiceProvider();
        rsa2.FromXmlString(privateKey);

        var encryptedBytes = rsa2.Encrypt(Encoding.UTF8.GetBytes(test), false);
        var encryptedString = Convert.ToBase64String(encryptedBytes);

        var rsa3 = new RSACryptoServiceProvider();
        rsa3.FromXmlString(pubicKey);

        encryptedBytes = Convert.FromBase64String(encryptedString);

        var decryptedString = Encoding.UTF8.GetString(rsa3.Decrypt(encryptedBytes,                        false));      

【问题讨论】:

  • 该软件正在他们的服务器上运行。如果“他们”确定足以窥视您的源代码以确定许可证文件是如何解码的,那么他们更改您的解码函数以返回他们想要的任何内容都是微不足道的。
  • 对……正如我在下面所说的那样。难道不能用私钥加密一些东西,然后只能用它的兄弟公钥解密加密的字符串吗?公钥将保存在他们的服务器上,他们永远无法访问私钥。
  • 请告诉我们密钥的托管位置。我猜你的意思是公钥由你的客户端托管,而私钥由你托管?
  • Greglev - 是的,公钥将存在于他们的服务器上。我认为公钥将用于解密用私钥加密的字符串。这样只有那个特定的公钥才能解密字符串。不是这样吗?
  • 请查看我作为答案提交的内容,它也解决了您的最后评论。简而言之,事实并非如此。

标签: c# asp.net asp.net-mvc encryption rsa


【解决方案1】:

您可以使用签名策略,其中私钥用于生成验证您的消息真实性的签名。

// Create message and signature on your end
string message = "Here is the license message";

var converter = new ASCIIEncoding();
byte[] plainText = converter.GetBytes(secret);

var rsaWrite = new RSACryptoServiceProvider();
var privateParams = rsaWrite.ExportParameters(true);

// Generate the public key / these can be sent to the user.
var publicParams = rsaWrite.ExportParameters(false);

byte[] signature =
    rsaWrite.SignData(plainText, new SHA1CryptoServiceProvider());

// Verify from the user's side. Note that only the public parameters
// are needed.
var rsaRead = new RSACryptoServiceProvider();
rsaRead.ImportParameters(publicParams);
if (rsaRead.VerifyData(plainText,
                       new SHA1CryptoServiceProvider(),
                       signature))
{
    Console.WriteLine("Verified!");
}
else
{
    Console.WriteLine("NOT verified!");
}

这个例子大部分是从微软的网站上复制的:

这里是解释这个概念的网页:

【讨论】:

    【解决方案2】:

    我认为您正在寻找的是数字签名。内容是否加密无关紧要,因为用户拥有(公共)密钥来解密它。重要的是内容的来源是否是您。 由于您有一个配置文件,我认为它是 XML,所以您正在寻找 XMLDSIG

    您可以使用 .Net 中的 SignedXml 类轻松实现此目的。然后您需要做的就是在加载配置文件时验证签名。此方法允许您轻松使用您可能拥有的任何 X509 证书。您甚至可以将公钥嵌入到签名文件中,因此用户无需安装您的证书(公钥)。

    【讨论】:

      【解决方案3】:

      您的想法是正确的,但我想知道无法预料的后果。

      您声明他们将在其服务器上运行软件,因此这意味着他们正在为自己托管服务。但是您还提到此服务必须连接到互联网才能通过验证您的服务器来添加用户。当互联网出现故障或他们想要一个安全的系统并且防火墙阻止互联网访问服务器时会发生什么?他们会完全失去运作的能力吗?

      只是给你一个问题来问自己:p

      【讨论】:

      • 对。如果他保持当前模型,他将需要某种可以工作一段时间的缓存,以便恢复互联网服务。
      • 不,我们不会“联系”我们的服务器来验证 Web 服务或任何相关的影响。我认为有意义的是,如果对于给定的安装,我生成了一个唯一的公钥/私钥,如果我用私钥加密了数据,那么只有它的兄弟公钥才能解密该字符串。不是这样吗?
      【解决方案4】:

      您不使用公钥来“解密”文件。您只能使用私钥解密文件。

      在您的情况下,您可以存储用户数量以及您使用私钥创建的数据的签名。

      在客户端服务器上,您使用您的公钥来验证签名与文件中的数据(用户数)是否匹配

      但是,高级用户可能会用他们自己的公钥替换您的公钥并自己签署文件。

      【讨论】:

      • 那么,正如您所说,这真的比加密更安全吗?没有什么能阻止任何人创建自己的公钥和签名?没有万无一失的方法可以防止某人这样做吗?
      • 解密数据和签名数据是不同的。我的观点是您无法使用公钥解密消息(操作:是否可以使用私有 rsa 密钥加密,然后使用公共密钥对其进行解密?)您无法从签名中提取纯文本消息。签名、纯文本消息和可信公钥验证消息来自私钥持有者。
      • 很好的澄清斯蒂芬。我删除了我的评论以避免混淆。
      【解决方案5】:

      正如您在问题中的评论中所述,您的方法是使用来自客户的密钥和来自您自己的密钥。这不起作用,因为 RSA 中使用的素数只能与相应的私钥/公钥一起使用。

      您需要使用您的两个密钥而不是来自客户端的任何内容或客户端的两个密钥而不是您的任何内容来执行此操作。例如,

      1. 您可以使用您的两个密钥对其进行签名,方法是使用您的私钥加密并允许客户端使用您的公钥解密。
      2. 您可以使用客户的公钥对其进行加密,并让他们使用他们(客户的)私钥进行解密。

      希望这会有所帮助!

      【讨论】:

      • Greg - 感谢您的帮助...不过,我认为使用公钥进行加密和解密都不是一种选择。如果是这样的话,他们可以编写一个程序,使用他们服务器上的公钥自己加密字符串。然后只需替换我的加密字符串。我的想法错了吗?
      • 我不认为这些话是完全正确的,买你的想法是正确的。我认为您可能意味着不能使用他们的密钥进行加密和解密?您认为他们可以随意更改它是正确的。我正在描述这两种方法。
      • 您需要使用第一个选项,这样只有您可以创建数据并使用您的私钥对其进行签名,让客户端使用您的公钥解密(验证签名)。
      • 格雷格,这是有道理的。但是是什么阻止他们在那里旋转自己的签名和公钥并交换我的。似乎也很容易绕过?
      • 正确,无论您是否混淆,他们都可以使用 .NET 轻松做到这一点。为了清楚起见,我的意思是他们可以重新编译您的代码并替换关键信息,但那时他们可能会删除类似的内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2013-06-08
      • 1970-01-01
      相关资源
      最近更新 更多