Skip to content

Commit e6a6c39

Browse files
committed
Add exception and test about rsa max length limit.
1 parent 40dbb5f commit e6a6c39

File tree

3 files changed

+129
-13
lines changed

3 files changed

+129
-13
lines changed

src/NETCore.Encrypt/EncryptProvider.cs

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private static string GetRandomStr(int length)
3030
StringBuilder num = new StringBuilder();
3131

3232
Random rnd = new Random(DateTime.Now.Millisecond);
33-
for (int i = 0; i < length; i++)
33+
for (int i = 0;i < length;i++)
3434
{
3535
num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());
3636
}
@@ -400,7 +400,7 @@ public static string DESDecrypt(string data, string key)
400400
{
401401
return null;
402402
}
403-
return Encoding.UTF8.GetString(bytes);
403+
return Encoding.UTF8.GetString(bytes);
404404
}
405405

406406
/// <summary>
@@ -476,7 +476,15 @@ public static string RSAEncrypt(string publicKey, string srcString, RSAEncryptio
476476
using (RSA rsa = RSA.Create())
477477
{
478478
rsa.FromJsonString(publicKey);
479-
byte[] encryptBytes = rsa.Encrypt(Encoding.UTF8.GetBytes(srcString), padding);
479+
var maxLength = GetMaxRsaEncryptLength(rsa, padding);
480+
var rawBytes = Encoding.UTF8.GetBytes(srcString);
481+
482+
if (rawBytes.Length > maxLength)
483+
{
484+
throw new OutofMaxlengthException(maxLength, $"'{srcString}' is out of max length");
485+
}
486+
487+
byte[] encryptBytes = rsa.Encrypt(rawBytes, padding);
480488
return encryptBytes.ToHexString();
481489
}
482490
}
@@ -538,7 +546,7 @@ public static RSAKey CreateRsaKey(RsaSize rsaSize = RsaSize.R2048)
538546
{
539547
using (RSA rsa = RSA.Create())
540548
{
541-
rsa.KeySize = (int)rsaSize;
549+
rsa.KeySize = (int) rsaSize;
542550

543551
string publicKey = rsa.ToJsonString(false);
544552
string privateKey = rsa.ToJsonString(true);
@@ -552,6 +560,47 @@ public static RSAKey CreateRsaKey(RsaSize rsaSize = RsaSize.R2048)
552560
};
553561
}
554562
}
563+
564+
/// <summary>
565+
/// Get rsa encrypt max length
566+
/// </summary>
567+
/// <param name="rsa">Rsa instance </param>
568+
/// <param name="padding"><see cref="RSAEncryptionPadding"/></param>
569+
/// <returns></returns>
570+
private static int GetMaxRsaEncryptLength(RSA rsa, RSAEncryptionPadding padding)
571+
{
572+
var offset = 0;
573+
if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1)
574+
{
575+
offset = 11;
576+
}
577+
else
578+
{
579+
if (padding.Equals(RSAEncryptionPadding.OaepSHA1))
580+
{
581+
offset = 42;
582+
}
583+
584+
if (padding.Equals(RSAEncryptionPadding.OaepSHA256))
585+
{
586+
offset = 66;
587+
}
588+
589+
if (padding.Equals(RSAEncryptionPadding.OaepSHA384))
590+
{
591+
offset = 98;
592+
}
593+
594+
if (padding.Equals(RSAEncryptionPadding.OaepSHA512))
595+
{
596+
offset = 130;
597+
}
598+
}
599+
var keySize = rsa.KeySize;
600+
var maxLength = keySize / 8 - offset;
601+
return maxLength;
602+
}
603+
555604
#endregion
556605

557606
#region MD5
@@ -862,7 +911,7 @@ private static string CreateMachineKey(int length)
862911
rng.GetBytes(random);
863912

864913
StringBuilder machineKey = new StringBuilder(length);
865-
for (int i = 0; i < random.Length; i++)
914+
for (int i = 0;i < random.Length;i++)
866915
{
867916
machineKey.Append(string.Format("{0:X2}", random[i]));
868917
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace NETCore.Encrypt
6+
{
7+
/// <summary>
8+
/// The encrypt string out of max length exception
9+
/// </summary>
10+
public class OutofMaxlengthException:Exception
11+
{
12+
/// <summary>
13+
/// The max length of ecnrypt data
14+
/// </summary>
15+
public int MaxLength { get; private set; }
16+
17+
/// <summary>
18+
/// Error message
19+
/// </summary>
20+
21+
public string ErrorMessage { get; set; }
22+
/// <summary>
23+
/// Ctor
24+
/// </summary>
25+
/// <param name="maxLength"></param>
26+
public OutofMaxlengthException(int maxLength)
27+
{
28+
MaxLength = maxLength;
29+
}
30+
31+
/// <summary>
32+
/// Ctor
33+
/// </summary>
34+
/// <param name="maxLength"></param>
35+
public OutofMaxlengthException(int maxLength, string message) : this(maxLength)
36+
{
37+
ErrorMessage = message;
38+
}
39+
}
40+
}

test/NETCore.Encrypt.Tests/RSA_Tests.cs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,18 @@ public void Rsa_Encrypt_LengthLimit_Test(RsaSize size)
165165
var rsaKey = EncryptProvider.CreateRsaKey(size);
166166

167167
var publicKey = rsaKey.PublicKey;
168+
var privateKey = rsaKey.PrivateKey;
168169

169170
//Act
170171
var rawStr = "eyJNb2R1bHVzIjoidHVSL1V1dFVSV0RSVElDYTFFRDcraUF2MUVnQUl0dC9oNkhHc0x6SG80QXAyVVdqWGtvRkp4T1NuRmdhY3d4cWM0WUg5UDdRaVIxQ1lCK3lvMnJUbkhZbVIrYWs2V3RJRU1YNWtmTTJrWHBNUVY2aFBrd0FxRTFpU1pWRUM2eXlmeTNGZUJTVmNnVlUwMFpJMGozbzhqT3ZMOXhneGhmT1J1eTcwM1RUbXdFPSIsIkV4cG9uZW50IjoiQVFBQiIsIlAiOiI3MVNIYVRnK2JvOXhzRnEzSXlrcHRFUXVHUXZTNDNEUDFoM04xcVlBN1E1VHpoS0IydEc1RWxvamtYTkF4d0VVVStxSnZMWDBxTHdzd09zRkhaL3lydz09IiwiUSI6Inc2R2ltem84a0lUL0xuS2U0Sk5QTUt2YTlVVzBSZUZlVzA5U1ZtVnFVWS9VeHl2eU9kemowd3JzTTZib1ZCU1JnZi9SbUZwRUZ1bUZTVW9yVWkxNVR3PT0iLCJEUCI6Im9yNXpPaXloMzZLeFozKzRhek54aFlDYmJES3JIRGc1VEZ1Ri9rRngvY0V4WWI4YUNFZDJ0ekVPWUxqandxOU1PR2dUYzN5enV3NEN6TWpEK01vc1J3PT0iLCJEUSI6InMvNGhhQVM2K0pVRlhDemxkT2JVTTRuTEdXUWFxempoNGMwbmlvb2d1ZzVGelVMbnlNa3RiRjFlV1YrMTNyWlY4bS8yM2VBZlNaMXRuckw1RE5EK0RRPT0iLCJJbnZlcnNlUSI6IlBPSkRGUk03MmVxd0R3TytldDFpTzIwTWlQcFVEUS93N1hEMHBMLzJWYTE4OEgrRGlaK0NuZDJRdnFYZyt4NFdNZSsrVlVNYXo2bWM3V1g4WnBaWW9RPT0iLCJEIjoiWE1QUEZPYktDcHFON21pNG4zb0tsSmFveTlwdFAwRG9FWXBydGc4NmoyS2RWMWZzQWhJM1JOZTNvRmRMcXhrY0VWWmxTTTNLUmhHeUxnRkY0WDk0cnVIYjBQeC9LZVQxMW1BeDNvQ2NCRVlWelhabXlIUHQzWCs2dlBMZzdmYUhtRmlxK3N0Y2NMTlBNSEdna2lkWTF6NGtiTXZwZnBlOWxhN0VMWUdKM21VPSJ9";
171172

172-
173173
//RSAEncryptionPaddingMode is Pkcs1
174174
var padding = RSAEncryptionPadding.Pkcs1;
175175
var maxLength = ((int) size - 384) / 8 + 37;
176176
var rawData = rawStr.Substring(0, maxLength);
177177

178-
var encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
179-
178+
var encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
179+
var decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
180180

181181
//RSAEncryptionPaddingMode is Oaep
182182
padding = RSAEncryptionPadding.OaepSHA1;
@@ -186,27 +186,54 @@ public void Rsa_Encrypt_LengthLimit_Test(RsaSize size)
186186
maxLength = (int) size / 8 - 42; //214 //40
187187
rawData = rawStr.Substring(0, maxLength);
188188

189-
encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
189+
encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
190+
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
191+
Assert.Equal(decryptedStr, rawData);
190192

191193

192194
padding = RSAEncryptionPadding.OaepSHA256;
193195

194196
maxLength = (int) size / 8 - 66; //190 //64
195197
rawData = rawStr.Substring(0, maxLength);
196198

197-
encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
199+
encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
200+
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
201+
202+
Assert.Equal(decryptedStr, rawData);
198203

199204
padding = RSAEncryptionPadding.OaepSHA384;
200-
maxLength = (int) size / 8 - 100; //158 //96
205+
maxLength = (int) size / 8 - 98; //158 //96
201206
rawData = rawStr.Substring(0, maxLength);
202207

203-
encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
208+
encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
209+
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
210+
211+
Assert.Equal(decryptedStr, rawData);
204212

205213
padding = RSAEncryptionPadding.OaepSHA512;
206214
maxLength = (int) size / 8 - 130; //126 // 128
207215
rawData = rawStr.Substring(0, maxLength);
208216

209-
encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
217+
encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
218+
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
219+
220+
Assert.Equal(decryptedStr, rawData);
221+
}
222+
223+
[Fact(DisplayName = "Rsa encrypt out of max length exception test")]
224+
public void Rsa_Encrypt_OutofMaxLength_Exception_Test()
225+
{
226+
//Act
227+
var rawStr = "eyJNb2R1bHVzIjoidHVSL1V1dFVSV0RSVElDYTFFRDcraUF2MUVnQUl0dC9oNkhHc0x6SG80QXAyVVdqWGtvRkp4T1NuRmdhY3d4cWM0WUg5UDdRaVIxQ1lCK3lvMnJUbkhZbVIrYWs2V3RJRU1YNWtmTTJrWHBNUVY2aFBrd0FxRTFpU1pWRUM2eXlmeTNGZUJTVmNnVlUwMFpJMGozbzhqT3ZMOXhneGhmT1J1eTcwM1RUbXdFPSIsIkV4cG9uZW50IjoiQVFBQiIsIlAiOiI3MVNIYVRnK2JvOXhzRnEzSXlrcHRFUXVHUXZTNDNEUDFoM04xcVlBN1E1VHpoS0IydEc1RWxvamtYTkF4d0VVVStxSnZMWDBxTHdzd09zRkhaL3lydz09IiwiUSI6Inc2R2ltem84a0lUL0xuS2U0Sk5QTUt2YTlVVzBSZUZlVzA5U1ZtVnFVWS9VeHl2eU9kemowd3JzTTZib1ZCU1JnZi9SbUZwRUZ1bUZTVW9yVWkxNVR3PT0iLCJEUCI6Im9yNXpPaXloMzZLeFozKzRhek54aFlDYmJES3JIRGc1VEZ1Ri9rRngvY0V4WWI4YUNFZDJ0ekVPWUxqandxOU1PR2dUYzN5enV3NEN6TWpEK01vc1J3PT0iLCJEUSI6InMvNGhhQVM2K0pVRlhDemxkT2JVTTRuTEdXUWFxempoNGMwbmlvb2d1ZzVGelVMbnlNa3RiRjFlV1YrMTNyWlY4bS8yM2VBZlNaMXRuckw1RE5EK0RRPT0iLCJJbnZlcnNlUSI6IlBPSkRGUk03MmVxd0R3TytldDFpTzIwTWlQcFVEUS93N1hEMHBMLzJWYTE4OEgrRGlaK0NuZDJRdnFYZyt4NFdNZSsrVlVNYXo2bWM3V1g4WnBaWW9RPT0iLCJEIjoiWE1QUEZPYktDcHFON21pNG4zb0tsSmFveTlwdFAwRG9FWXBydGc4NmoyS2RWMWZzQWhJM1JOZTNvRmRMcXhrY0VWWmxTTTNLUmhHeUxnRkY0WDk0cnVIYjBQeC9LZVQxMW1BeDNvQ2NCRVlWelhabXlIUHQzWCs2dlBMZzdmYUhtRmlxK3N0Y2NMTlBNSEdna2lkWTF6NGtiTXZwZnBlOWxhN0VMWUdKM21VPSJ9";
228+
229+
var rsaKey = EncryptProvider.CreateRsaKey();
230+
var publicKey = rsaKey.PublicKey;
231+
232+
//Assert
233+
Assert.Throws<OutofMaxlengthException>(() =>
234+
{
235+
EncryptProvider.RSAEncrypt(publicKey, rawStr);
236+
});
210237
}
211238
}
212239
}

0 commit comments

Comments
 (0)