Skip to content

Commit

Permalink
Merge pull request #19 from myloveCc/dev
Browse files Browse the repository at this point in the history
Add OutofMaxlengthException
  • Loading branch information
myloveCc authored Jun 5, 2018
2 parents 5cabc21 + 55f7da8 commit 6988f87
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 11 deletions.
59 changes: 54 additions & 5 deletions src/NETCore.Encrypt/EncryptProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private static string GetRandomStr(int length)
StringBuilder num = new StringBuilder();

Random rnd = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < length; i++)
for (int i = 0;i < length;i++)
{
num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());
}
Expand Down Expand Up @@ -400,7 +400,7 @@ public static string DESDecrypt(string data, string key)
{
return null;
}
return Encoding.UTF8.GetString(bytes);
return Encoding.UTF8.GetString(bytes);
}

/// <summary>
Expand Down Expand Up @@ -476,7 +476,15 @@ public static string RSAEncrypt(string publicKey, string srcString, RSAEncryptio
using (RSA rsa = RSA.Create())
{
rsa.FromJsonString(publicKey);
byte[] encryptBytes = rsa.Encrypt(Encoding.UTF8.GetBytes(srcString), padding);
var maxLength = GetMaxRsaEncryptLength(rsa, padding);
var rawBytes = Encoding.UTF8.GetBytes(srcString);

if (rawBytes.Length > maxLength)
{
throw new OutofMaxlengthException(maxLength, $"'{srcString}' is out of max length");
}

byte[] encryptBytes = rsa.Encrypt(rawBytes, padding);
return encryptBytes.ToHexString();
}
}
Expand Down Expand Up @@ -538,7 +546,7 @@ public static RSAKey CreateRsaKey(RsaSize rsaSize = RsaSize.R2048)
{
using (RSA rsa = RSA.Create())
{
rsa.KeySize = (int)rsaSize;
rsa.KeySize = (int) rsaSize;

string publicKey = rsa.ToJsonString(false);
string privateKey = rsa.ToJsonString(true);
Expand All @@ -552,6 +560,47 @@ public static RSAKey CreateRsaKey(RsaSize rsaSize = RsaSize.R2048)
};
}
}

/// <summary>
/// Get rsa encrypt max length
/// </summary>
/// <param name="rsa">Rsa instance </param>
/// <param name="padding"><see cref="RSAEncryptionPadding"/></param>
/// <returns></returns>
private static int GetMaxRsaEncryptLength(RSA rsa, RSAEncryptionPadding padding)
{
var offset = 0;
if (padding.Mode == RSAEncryptionPaddingMode.Pkcs1)
{
offset = 11;
}
else
{
if (padding.Equals(RSAEncryptionPadding.OaepSHA1))
{
offset = 42;
}

if (padding.Equals(RSAEncryptionPadding.OaepSHA256))
{
offset = 66;
}

if (padding.Equals(RSAEncryptionPadding.OaepSHA384))
{
offset = 98;
}

if (padding.Equals(RSAEncryptionPadding.OaepSHA512))
{
offset = 130;
}
}
var keySize = rsa.KeySize;
var maxLength = keySize / 8 - offset;
return maxLength;
}

#endregion

#region MD5
Expand Down Expand Up @@ -862,7 +911,7 @@ private static string CreateMachineKey(int length)
rng.GetBytes(random);

StringBuilder machineKey = new StringBuilder(length);
for (int i = 0; i < random.Length; i++)
for (int i = 0;i < random.Length;i++)
{
machineKey.Append(string.Format("{0:X2}", random[i]));
}
Expand Down
40 changes: 40 additions & 0 deletions src/NETCore.Encrypt/Exception/OutofMaxlengthException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace NETCore.Encrypt
{
/// <summary>
/// The encrypt string out of max length exception
/// </summary>
public class OutofMaxlengthException:Exception
{
/// <summary>
/// The max length of ecnrypt data
/// </summary>
public int MaxLength { get; private set; }

/// <summary>
/// Error message
/// </summary>

public string ErrorMessage { get; set; }
/// <summary>
/// Ctor
/// </summary>
/// <param name="maxLength"></param>
public OutofMaxlengthException(int maxLength)
{
MaxLength = maxLength;
}

/// <summary>
/// Ctor
/// </summary>
/// <param name="maxLength"></param>
public OutofMaxlengthException(int maxLength, string message) : this(maxLength)
{
ErrorMessage = message;
}
}
}
12 changes: 6 additions & 6 deletions src/NETCore.Encrypt/NETCore.Encrypt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
<Product>Lvcc</Product>
<Authors>Lvcc</Authors>
<Description>NETCore encrypt and decrpty tool,Include AES,RSA,MD5,SAH1,SAH256,SHA384,SHA512</Description>
<Copyright>Copyright 2017 (c) Lvcc. All rights reserved</Copyright>
<Copyright>Copyright 2018 (c) Lvcc. All rights reserved</Copyright>
<PackageLicenseUrl>https://github.com/myloveCc/NETCore.Encrypt/blob/master/License</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/myloveCc/NETCore.Encrypt</PackageProjectUrl>
<RepositoryUrl>https://github.com/myloveCc/NETCore.Encrypt</RepositoryUrl>
<RepositoryType>Github</RepositoryType>
<AssemblyVersion>2.0.6.0</AssemblyVersion>
<FileVersion>2.0.6.0</FileVersion>
<Version>2.0.6</Version>
<PackageReleaseNotes>1: Add demo about how to use.
2: Add new method for aes/des with byte[] encrypt/decrypt.
<AssemblyVersion>2.0.7.0</AssemblyVersion>
<FileVersion>2.0.7.0</FileVersion>
<Version>2.0.7</Version>
<PackageReleaseNotes>1: Add OutofMaxlengthException for rsa encrypt.
2: Add test about rsa OutofMaxlengthException.
</PackageReleaseNotes>
</PropertyGroup>

Expand Down
81 changes: 81 additions & 0 deletions test/NETCore.Encrypt.Tests/RSA_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Xunit;
using NETCore.Encrypt;
using System.Security.Cryptography;
using NETCore.Encrypt.Extensions;

namespace NETCore.Encrypt.Tests
{
Expand Down Expand Up @@ -154,5 +155,85 @@ public void Rsa_From_JsonString_Test()
Assert.NotNull(rsa);

}

[Theory(DisplayName = "Rsa encrypt string length limit test")]
[InlineData(RsaSize.R2048)]
[InlineData(RsaSize.R3072)]
[InlineData(RsaSize.R4096)]
public void Rsa_Encrypt_LengthLimit_Test(RsaSize size)
{
var rsaKey = EncryptProvider.CreateRsaKey(size);

var publicKey = rsaKey.PublicKey;
var privateKey = rsaKey.PrivateKey;

//Act
var rawStr = "eyJNb2R1bHVzIjoidHVSL1V1dFVSV0RSVElDYTFFRDcraUF2MUVnQUl0dC9oNkhHc0x6SG80QXAyVVdqWGtvRkp4T1NuRmdhY3d4cWM0WUg5UDdRaVIxQ1lCK3lvMnJUbkhZbVIrYWs2V3RJRU1YNWtmTTJrWHBNUVY2aFBrd0FxRTFpU1pWRUM2eXlmeTNGZUJTVmNnVlUwMFpJMGozbzhqT3ZMOXhneGhmT1J1eTcwM1RUbXdFPSIsIkV4cG9uZW50IjoiQVFBQiIsIlAiOiI3MVNIYVRnK2JvOXhzRnEzSXlrcHRFUXVHUXZTNDNEUDFoM04xcVlBN1E1VHpoS0IydEc1RWxvamtYTkF4d0VVVStxSnZMWDBxTHdzd09zRkhaL3lydz09IiwiUSI6Inc2R2ltem84a0lUL0xuS2U0Sk5QTUt2YTlVVzBSZUZlVzA5U1ZtVnFVWS9VeHl2eU9kemowd3JzTTZib1ZCU1JnZi9SbUZwRUZ1bUZTVW9yVWkxNVR3PT0iLCJEUCI6Im9yNXpPaXloMzZLeFozKzRhek54aFlDYmJES3JIRGc1VEZ1Ri9rRngvY0V4WWI4YUNFZDJ0ekVPWUxqandxOU1PR2dUYzN5enV3NEN6TWpEK01vc1J3PT0iLCJEUSI6InMvNGhhQVM2K0pVRlhDemxkT2JVTTRuTEdXUWFxempoNGMwbmlvb2d1ZzVGelVMbnlNa3RiRjFlV1YrMTNyWlY4bS8yM2VBZlNaMXRuckw1RE5EK0RRPT0iLCJJbnZlcnNlUSI6IlBPSkRGUk03MmVxd0R3TytldDFpTzIwTWlQcFVEUS93N1hEMHBMLzJWYTE4OEgrRGlaK0NuZDJRdnFYZyt4NFdNZSsrVlVNYXo2bWM3V1g4WnBaWW9RPT0iLCJEIjoiWE1QUEZPYktDcHFON21pNG4zb0tsSmFveTlwdFAwRG9FWXBydGc4NmoyS2RWMWZzQWhJM1JOZTNvRmRMcXhrY0VWWmxTTTNLUmhHeUxnRkY0WDk0cnVIYjBQeC9LZVQxMW1BeDNvQ2NCRVlWelhabXlIUHQzWCs2dlBMZzdmYUhtRmlxK3N0Y2NMTlBNSEdna2lkWTF6NGtiTXZwZnBlOWxhN0VMWUdKM21VPSJ9";

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

var encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
var decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);

//RSAEncryptionPaddingMode is Oaep
padding = RSAEncryptionPadding.OaepSHA1;

var sha1 = "oaep".SHA1();
var length = sha1.Length;
maxLength = (int) size / 8 - 42; //214 //40
rawData = rawStr.Substring(0, maxLength);

encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);
Assert.Equal(decryptedStr, rawData);


padding = RSAEncryptionPadding.OaepSHA256;

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

encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);

Assert.Equal(decryptedStr, rawData);

padding = RSAEncryptionPadding.OaepSHA384;
maxLength = (int) size / 8 - 98; //158 //96
rawData = rawStr.Substring(0, maxLength);

encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);

Assert.Equal(decryptedStr, rawData);

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

encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding);
decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding);

Assert.Equal(decryptedStr, rawData);
}

[Fact(DisplayName = "Rsa encrypt out of max length exception test")]
public void Rsa_Encrypt_OutofMaxLength_Exception_Test()
{
//Act
var rawStr = "eyJNb2R1bHVzIjoidHVSL1V1dFVSV0RSVElDYTFFRDcraUF2MUVnQUl0dC9oNkhHc0x6SG80QXAyVVdqWGtvRkp4T1NuRmdhY3d4cWM0WUg5UDdRaVIxQ1lCK3lvMnJUbkhZbVIrYWs2V3RJRU1YNWtmTTJrWHBNUVY2aFBrd0FxRTFpU1pWRUM2eXlmeTNGZUJTVmNnVlUwMFpJMGozbzhqT3ZMOXhneGhmT1J1eTcwM1RUbXdFPSIsIkV4cG9uZW50IjoiQVFBQiIsIlAiOiI3MVNIYVRnK2JvOXhzRnEzSXlrcHRFUXVHUXZTNDNEUDFoM04xcVlBN1E1VHpoS0IydEc1RWxvamtYTkF4d0VVVStxSnZMWDBxTHdzd09zRkhaL3lydz09IiwiUSI6Inc2R2ltem84a0lUL0xuS2U0Sk5QTUt2YTlVVzBSZUZlVzA5U1ZtVnFVWS9VeHl2eU9kemowd3JzTTZib1ZCU1JnZi9SbUZwRUZ1bUZTVW9yVWkxNVR3PT0iLCJEUCI6Im9yNXpPaXloMzZLeFozKzRhek54aFlDYmJES3JIRGc1VEZ1Ri9rRngvY0V4WWI4YUNFZDJ0ekVPWUxqandxOU1PR2dUYzN5enV3NEN6TWpEK01vc1J3PT0iLCJEUSI6InMvNGhhQVM2K0pVRlhDemxkT2JVTTRuTEdXUWFxempoNGMwbmlvb2d1ZzVGelVMbnlNa3RiRjFlV1YrMTNyWlY4bS8yM2VBZlNaMXRuckw1RE5EK0RRPT0iLCJJbnZlcnNlUSI6IlBPSkRGUk03MmVxd0R3TytldDFpTzIwTWlQcFVEUS93N1hEMHBMLzJWYTE4OEgrRGlaK0NuZDJRdnFYZyt4NFdNZSsrVlVNYXo2bWM3V1g4WnBaWW9RPT0iLCJEIjoiWE1QUEZPYktDcHFON21pNG4zb0tsSmFveTlwdFAwRG9FWXBydGc4NmoyS2RWMWZzQWhJM1JOZTNvRmRMcXhrY0VWWmxTTTNLUmhHeUxnRkY0WDk0cnVIYjBQeC9LZVQxMW1BeDNvQ2NCRVlWelhabXlIUHQzWCs2dlBMZzdmYUhtRmlxK3N0Y2NMTlBNSEdna2lkWTF6NGtiTXZwZnBlOWxhN0VMWUdKM21VPSJ9";

var rsaKey = EncryptProvider.CreateRsaKey();
var publicKey = rsaKey.PublicKey;

//Assert
Assert.Throws<OutofMaxlengthException>(() =>
{
EncryptProvider.RSAEncrypt(publicKey, rawStr);
});
}
}
}

0 comments on commit 6988f87

Please sign in to comment.