【问题标题】:RSA: Using public key for decryption in .NET?RSA:在 .NET 中使用公钥解密?
【发布时间】:2011-03-14 18:04:23
【问题描述】:

我在使用 MS .NET 的 RSA 加密/解密功能时遇到问题:

看来,.NET does not support 使用私钥进行加密,使用相应的公钥进行解密。 (据我了解,这样做会以某种方式侵犯算法的安全性。)

好的,但是例如当我在构建程序集上签名时,似乎the compiler just does that:“编译器使用您的公私钥对文件中的 1024 位私钥加密摘要。”

那么,如果我无法说服 RSACryptoServiceProvider 使用公钥进行解密,我该如何实现类似编译器的功能?

我只想用我的私钥加密几个字节并用公钥解密它,用于一些非关键任务。如果一个编程极客设法打破这个计划,我会活下去。我只是想防止不懂技术的 John Doe 窥探。

对此的任何建议将不胜感激。

问候 伯蒂

编辑:建议使用 Usign SignData() 和 VerifySign(),但我只能比较哈希是否相等。但是,我需要检索已加密/签名的原始输入。

【问题讨论】:

标签: .net rsa


【解决方案1】:

.Net 确实支持它,但该概念称为“签名”并使用 RSACryptoServiceProvider 的 SignData() 方法。从技术上讲,它正在创建要签名的数据的散列,然后用私钥加密该散列。

我认为他们不支持使用私钥任意加密的原因是为了确保您的代码中有良好的安全实践,这样您就不会意外地使用错误的密钥进行加密,或者您不会使用不安全的制作签名的技术。

请参阅SignData 上的文档以获取示例代码。

【讨论】:

  • 请注意,签名不能用于发送加密数据。它只能用于检查数据是否与签名匹配。
  • 如果我理解正确,那么使用 SignData() 只能让我检查哈希是否相等。但由于输入被散列,我无法检索原始输入。但是,我需要该输入作为纯文本。没有办法找回吗?
【解决方案2】:

这是我的代码,仍有一些缺陷,但在大多数情况下都有效。 我通过 Java 得到 modulusString

public static string Decrypt(string text, string modulusString)
{
    var modulus = BigInteger.Parse(modulusString);
    var exponent = BigInteger.Parse("65537");

    var encryptBytes = Convert.FromBase64String(text);

    if (publicKey.Modulus.Length > 309) // long enough key to decrypt short message
    {
        return Decrypt(encryptBytes, exponent, modulus);
    }

    string result = string.Empty;
    int i = 0;
    while (i < encryptBytes.Length) // for short key, must decrypt section-by-section
    {
        var temp = new byte[Math.Min(encryptBytes.Length, 128)];
        Array.Copy(encryptBytes, i, temp, 0, temp.Length);
        result += Decrypt(temp, exponent, modulus);
        i += 128;
    }
    return result;
}

private static string Decrypt(byte[] encryptBytes, BigInteger exponent, BigInteger modulus)
{
    Array.Reverse(encryptBytes); // BigIntenger need little-endian
    if ((encryptBytes[encryptBytes.Length - 1] & 0x80) > 0) // make positive
    {
        var temp = new byte[encryptBytes.Length];
        Array.Copy(encryptBytes, temp, encryptBytes.Length);
        encryptBytes = new byte[temp.Length + 1];
        Array.Copy(temp, encryptBytes, temp.Length);
    }
    var value = new BigInteger(encryptBytes);

    var result = BigInteger.ModPow(value, exponent, modulus);
    byte[] resultBytes = result.ToByteArray();
    Array.Reverse(resultBytes);

    int index = Array.FindIndex(resultBytes, b => b == 0) + 1;
    return Encoding.UTF8.GetString(resultBytes, index, resultBytes.Length - index);
}

【讨论】:

    猜你喜欢
    • 2021-10-03
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2012-05-07
    • 2011-03-08
    • 2020-02-28
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多