RSA:在.NET中使用公钥进行解密?

时间:2011-03-14 18:04:24

标签: .net rsa

我遇到了MS .NET的RSA加密/解密功能问题:

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

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

所以,如果我不能说服RSACryptoServiceProvider使用公钥进行解密,我怎样才能实现像编译器类似的东西呢?

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

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

电贺 berntie

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

2 个答案:

答案 0 :(得分:3)

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

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

请参阅SignData上的文档,例如代码。

答案 1 :(得分:0)

这是我的代码,仍有一些缺陷但在大多数情况下都有效。 我通过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);
}