2011-03-14 343 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); 
}