2011-03-14 177 views
3

我在与MS .NET的RSA加密/解密功能的问题:RSA:在.NET中使用公钥解密?

看来,.NET does not support使用加密和私钥用于解密相应的公钥。 (据我所知,这样做的方式,不知何故侵犯了算法的安全性。)

好吧,但例如当我在建筑物上签署一个程序集时,它似乎the compiler just does that:“编译器使用1024加密摘要从你的公私密钥对文件中找到私钥。“

因此,如果我不能说服RSACryptoServiceProvider使用公共密钥进行解密,我该如何实现类似编译器的类似功能?

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

任何意见,将不胜感激。

电贺 berntie

编辑:Usign SignData()和VerifySign()已经提出,但当时我只能比较哈希值是否相等。但是,我需要检索加密/签名的原始输入。

+0

我假设你检查了这一点完全http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx – Venki 2011-03-14 18:11:23

回答

2

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

我认为他们不支持用私钥进行任意加密的原因是为了确保代码中有良好的安全措施,以免意外使用错误的密钥进行加密或者您不使用用于制作签名的不安全技术。

有关示例代码,请参阅SignData上的文档。

+1

注意签署能不能用来发送加密数据。它只能用于检查数据是否与签名匹配。 – mgronber 2011-03-14 18:21:40

+1

如果我理解正确,那么使用SignData()只能让我检查散列的相等性。但是由于输入被哈希,我无法检索原始输入。但是,我需要输入明文。没有办法检索它吗? – berntie 2011-03-14 22:27:14

-1

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