简体   繁体   English

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

[英]RSA: Using public key for decryption in .NET?

I'm having issues with the RSA encryption/decryption capabilities of MS .NET: 我遇到了MS .NET的RSA加密/解密功能问题:

It seems, .NET does not support using a private key for encryption and the corresponding public key for decryption. 看来, .NET不支持使用私钥进行加密, 也不支持使用相应的公钥进行解密。 (As I understand, doing it that way round, somehow infringes the security of the algorithm.) (据我所知,这样做会以某种方式侵犯算法的安全性。)

Ok, but for example when I sign an assembly on building, it seems the compiler just does that : "The compiler encrypts the digest using the 1024-bit private key from your public-private key pair file." 好吧,但是例如当我在构建时签署程序集时, 编译器似乎只是这样做 :“编译器使用公钥 - 私钥对文件中的1024位私钥加密摘要。”

So, if I cannot convince the RSACryptoServiceProvider to use a public key for decrypting, how can I achieve something similar like the compiler? 所以,如果我不能说服RSACryptoServiceProvider使用公钥进行解密,我怎样才能实现像编译器类似的东西呢?

I just want to encrypt a few bytes with my private key and decrypt it with the public key, for some non-critical task. 我只想用我的私钥加密几个字节并用公钥解密它,用于一些非关键任务。 If a programming geek manages to break that scheme, I'll live. 如果编程爱好者设法打破这个计划,我会活下去。 I just want to prevent the non-tech-savvy John Doe from snooping around. 我只是想阻止非技术娴熟的John Doe窥探。

Any advice on this would be appreciated. 对此有任何建议将不胜感激。

Greets berntie 问候berntie

Edit: Usign SignData() and VerifySign() has been suggested, but then I can only compare hashes for equality. 编辑:建议使用SignData()和VerifySign(),但之后我只能比较哈希的相等性。 However, I need to retrieve the original input that was encrypted/signed. 但是,我需要检索加密/签名的原始输入。

.Net does support it, but that concept is called "Signing" and uses the SignData() method of RSACryptoServiceProvider . .Net确实支持它,但该概念称为“签名”并使用RSACryptoServiceProvider的SignData()方法。 Technically, what's happening is it's creating a hash of the data to be signed, then encrypting that hash with the private key. 从技术上讲,正在发生的是创建要签名的数据的哈希值,然后使用私钥加密该哈希值。

I think the reason they don't support arbitrarily encrypting with the private key is to ensure good security practices in your code, so that you don't accidentally encrypt with the wrong key, or that you don't use an insecure technique for making the signature. 我认为他们不支持使用私钥进行任意加密的原因是为了确保代码中的良好安全实践,这样您就不会意外地使用错误的密钥加密,或者您不使用不安全的技术来制作签名。

See the documentation on SignData for example code. 有关示例代码,请参阅SignData文档。

Here is my code, still has some defect but worked in most situation. 这是我的代码,仍然有一些缺陷,但在大多数情况下工作。 I get modulusString by Java. 我通过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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM