[C#.NET] RSA 的長度限制
續上篇,[C#.NET] 字串及檔案,利用 RSA 演算法加解密
RSA加密演算法不利於大資料的加密,因為它在演算過程中很耗時,所以非對稱加密 RSA 僅適合小資料的加密,大資料得用對稱加密AES/DES。
對於大資料(byte[]長度過長),.NET直接宣判死型
趴一下文就可以找到一些線索:
http://www.dotblogs.com.tw/sin1980/archive/2012/01/20/66797.aspx
將取得的公式套用至程式碼裡,這表示我們必須要分段處理,並驗証公式的值是否能被.NET的RSA所接受,在這裡就不做這個驗証動作了,因為我在幾個月前就驗過了,有興趣的人可以自己試試看。
把encryptor方法改成分段處理,如下:
private byte[] encryptor(byte[] OriginalData)
{
if (OriginalData == null || OriginalData.Length <= 0)
{
throw new NotSupportedException();
}
if (this._rsaCrypto == null)
{
throw new ArgumentNullException();
}
this._rsaCrypto.FromXmlString(this.PublicKey);
int bufferSize = (this._rsaCrypto.KeySize / 8) - 11;
byte[] buffer = new byte[bufferSize];
//分段加密
using (MemoryStream input = new MemoryStream(OriginalData))
using (MemoryStream ouput = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, bufferSize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] encrypt = this._rsaCrypto.Encrypt(temp, false);
ouput.Write(encrypt, 0, encrypt.Length);
}
return ouput.ToArray();
}
}
加密是分段處理,解密一樣也是要分段處理,解密處理的byte數跟加密不一樣唷,所以將decryptor改成以下:
private byte[] decryptor(byte[] EncryptDada)
{
if (EncryptDada == null || EncryptDada.Length <= 0)
{
throw new NotSupportedException();
}
this._rsaCrypto.FromXmlString(this.PrivateKey);
int keySize = this._rsaCrypto.KeySize / 8; byte[] buffer = new byte[keySize];
using (MemoryStream input = new MemoryStream(EncryptDada))
using (MemoryStream output = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, keySize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] decrypt = _rsaCrypto.Decrypt(temp, false);
output.Write(decrypt, 0, decrypt.Length);
}
return output.ToArray();
}
}
咱們利用單元測試來觀察
[TestMethod()]
public void EncryptStringTest()
{
RasCryptorService target = new RasCryptorService(); // TODO: Initialize to an appropriate value
string OriginalString =
@"
http://tw.news.yahoo.com/nba--nba-%E7%86%B1%E7%81%AB%E7%B5%82%E6%A5%B5%E5%BB%B6%E7%87%92-%E6%88%90%E5%B0%B1%E9%9A%8A%E5%8F%B2%E7%AC%AC2%E5%86%A0.html
總冠軍賽第4戰大腿抽筋的LeBron James今天(22日)順利出賽,更繳出大三元的成績單,加上Mike Miller單場7個三分球的最大助力,最終熱火121比106擊敗雷霆,以4勝1敗戰績成就隊史第2座總冠軍。
熱火取得聽牌第4戰勝利後,第5場比賽全隊氣勢來到頂點,上半場就以較佳準度取得10分領先,第3節一波16比0高潮更把差距擴大25分之多,而熱火之所以將差距擴大,除三焱James、Chris Bosh、Dwyane Wade的穩健演出,Miller狂飆7個三分球也是關鍵。
James繳出26分11籃板13助攻的大三元成績單,更重要的是他終於在進入NBA第9年圓了總冠軍的夢想,也圓滿達成總冠軍賽賽前燃燒一切絕不後悔的宣言。
熱火Miller全場飆進7個三分球貢獻23分,他屢屢以長程火砲重創雷霆士氣,熾熱演出完全不輸James;Wade有著20分8籃板3助攻2抄截3火鍋,Bosh則是24分7籃板,Mario Chalmers則是10分7助攻。
雷霆在前場狂飆43分的Russell Westbrook演出失常、James Harden手感依舊未恢復的情況下,僅靠Kevin Durant難撐大局,雷霆試圖將戰局延長到主場的企圖至此破滅。
Durant攻下32分11籃板但也發生7次失誤,Westbrook「僅」獲19分6助攻,Harden則是14分4籃板4助攻,除Durant的24投13中的優異準度外,Westbrook與Harden是令人失望的31投9中。老將Derek Fisher則砍進11分。
";
string expected = string.Empty;
string actual;
actual = target.EncryptString(OriginalString);
//Assert.AreEqual(expected, actual);
}
這次資料長度來到了1613
仍可順利的加密,只是無法設定斷點比對加密資料,相同資料每次加密的結果都不一樣,看來加密資料似乎已經加鹽了。
像這樣每次的結果都不一樣,該如何提高可測試性?知道的前輩能跟我講一下嗎?
解密資料:
[TestMethod()]
public void DecryptStringTest()
{
RasCryptorService target = new RasCryptorService();
string EncryptString = "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";
string expected =
@"
http://tw.news.yahoo.com/nba--nba-%E7%86%B1%E7%81%AB%E7%B5%82%E6%A5%B5%E5%BB%B6%E7%87%92-%E6%88%90%E5%B0%B1%E9%9A%8A%E5%8F%B2%E7%AC%AC2%E5%86%A0.html
總冠軍賽第4戰大腿抽筋的LeBron James今天(22日)順利出賽,更繳出大三元的成績單,加上Mike Miller單場7個三分球的最大助力,最終熱火121比106擊敗雷霆,以4勝1敗戰績成就隊史第2座總冠軍。
熱火取得聽牌第4戰勝利後,第5場比賽全隊氣勢來到頂點,上半場就以較佳準度取得10分領先,第3節一波16比0高潮更把差距擴大25分之多,而熱火之所以將差距擴大,除三焱James、Chris Bosh、Dwyane Wade的穩健演出,Miller狂飆7個三分球也是關鍵。
James繳出26分11籃板13助攻的大三元成績單,更重要的是他終於在進入NBA第9年圓了總冠軍的夢想,也圓滿達成總冠軍賽賽前燃燒一切絕不後悔的宣言。
熱火Miller全場飆進7個三分球貢獻23分,他屢屢以長程火砲重創雷霆士氣,熾熱演出完全不輸James;Wade有著20分8籃板3助攻2抄截3火鍋,Bosh則是24分7籃板,Mario Chalmers則是10分7助攻。
雷霆在前場狂飆43分的Russell Westbrook演出失常、James Harden手感依舊未恢復的情況下,僅靠Kevin Durant難撐大局,雷霆試圖將戰局延長到主場的企圖至此破滅。
Durant攻下32分11籃板但也發生7次失誤,Westbrook「僅」獲19分6助攻,Harden則是14分4籃板4助攻,除Durant的24投13中的優異準度外,Westbrook與Harden是令人失望的31投9中。老將Derek Fisher則砍進11分。
";
string actual;
actual = target.DecryptString(EncryptString);
Assert.AreEqual(expected, actual);
}
當然,這也通過測試了。
接下來測試檔案加密,這次的測試檔是足足有9M之大
單元測試長這樣:
[TestMethod()]
[DeploymentItem("余小章.bmp")]
public void EncryptFileTest()
{
RasCryptorService target = new RasCryptorService();
string OriginalFile = "余小章.bmp";
string EncrytpFile = "余小章.rsabmp";
target.EncryptFile(OriginalFile, EncrytpFile);
Assert.AreEqual(true, File.Exists(EncrytpFile));
}
9M花了3秒多,尚可接受啦~
檔案解密單元測試
[TestMethod()]
[DeploymentItem("余小章.rsabmp")]
public void DecryptFileTest()
{
RasCryptorService target = new RasCryptorService();
string EncrytpFile = "余小章.rsabmp";
string DecrytpFile = "余小章-1.bmp";
target.DecryptFile(EncrytpFile, DecrytpFile);
Assert.AreEqual(true, File.Exists(DecrytpFile));
}
這次跑了兩分多鐘,害我以為電腦掛點了。
來看一下解密後的小章,依然帥氣~XD
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET