From 40dbb5f143046e67b1b429eab156ceefc142330f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=7E?= Date: Tue, 5 Jun 2018 11:52:59 +0800 Subject: [PATCH 1/3] Add test about rsa encrypt string length limit. --- test/NETCore.Encrypt.Tests/RSA_Tests.cs | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/NETCore.Encrypt.Tests/RSA_Tests.cs b/test/NETCore.Encrypt.Tests/RSA_Tests.cs index cc2c812..6863ff9 100644 --- a/test/NETCore.Encrypt.Tests/RSA_Tests.cs +++ b/test/NETCore.Encrypt.Tests/RSA_Tests.cs @@ -4,6 +4,7 @@ using Xunit; using NETCore.Encrypt; using System.Security.Cryptography; +using NETCore.Encrypt.Extensions; namespace NETCore.Encrypt.Tests { @@ -154,5 +155,58 @@ 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; + + //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 encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, 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); + + encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + + + padding = RSAEncryptionPadding.OaepSHA256; + + maxLength = (int) size / 8 - 66; //190 //64 + rawData = rawStr.Substring(0, maxLength); + + encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + + padding = RSAEncryptionPadding.OaepSHA384; + maxLength = (int) size / 8 - 100; //158 //96 + rawData = rawStr.Substring(0, maxLength); + + encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + + padding = RSAEncryptionPadding.OaepSHA512; + maxLength = (int) size / 8 - 130; //126 // 128 + rawData = rawStr.Substring(0, maxLength); + + encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + } } } From e6a6c39bae361bd98ce2319e877dbcf668ac3cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=7E?= Date: Tue, 5 Jun 2018 12:27:23 +0800 Subject: [PATCH 2/3] Add exception and test about rsa max length limit. --- src/NETCore.Encrypt/EncryptProvider.cs | 59 +++++++++++++++++-- .../Exception/OutofMaxlengthException.cs | 40 +++++++++++++ test/NETCore.Encrypt.Tests/RSA_Tests.cs | 43 +++++++++++--- 3 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 src/NETCore.Encrypt/Exception/OutofMaxlengthException.cs diff --git a/src/NETCore.Encrypt/EncryptProvider.cs b/src/NETCore.Encrypt/EncryptProvider.cs index f2cdf34..f20f280 100644 --- a/src/NETCore.Encrypt/EncryptProvider.cs +++ b/src/NETCore.Encrypt/EncryptProvider.cs @@ -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()); } @@ -400,7 +400,7 @@ public static string DESDecrypt(string data, string key) { return null; } - return Encoding.UTF8.GetString(bytes); + return Encoding.UTF8.GetString(bytes); } /// @@ -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(); } } @@ -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); @@ -552,6 +560,47 @@ public static RSAKey CreateRsaKey(RsaSize rsaSize = RsaSize.R2048) }; } } + + /// + /// Get rsa encrypt max length + /// + /// Rsa instance + /// + /// + 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 @@ -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])); } diff --git a/src/NETCore.Encrypt/Exception/OutofMaxlengthException.cs b/src/NETCore.Encrypt/Exception/OutofMaxlengthException.cs new file mode 100644 index 0000000..1155f26 --- /dev/null +++ b/src/NETCore.Encrypt/Exception/OutofMaxlengthException.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NETCore.Encrypt +{ + /// + /// The encrypt string out of max length exception + /// + public class OutofMaxlengthException:Exception + { + /// + /// The max length of ecnrypt data + /// + public int MaxLength { get; private set; } + + /// + /// Error message + /// + + public string ErrorMessage { get; set; } + /// + /// Ctor + /// + /// + public OutofMaxlengthException(int maxLength) + { + MaxLength = maxLength; + } + + /// + /// Ctor + /// + /// + public OutofMaxlengthException(int maxLength, string message) : this(maxLength) + { + ErrorMessage = message; + } + } +} diff --git a/test/NETCore.Encrypt.Tests/RSA_Tests.cs b/test/NETCore.Encrypt.Tests/RSA_Tests.cs index 6863ff9..b108837 100644 --- a/test/NETCore.Encrypt.Tests/RSA_Tests.cs +++ b/test/NETCore.Encrypt.Tests/RSA_Tests.cs @@ -165,18 +165,18 @@ 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 encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); - + var encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + var decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding); //RSAEncryptionPaddingMode is Oaep padding = RSAEncryptionPadding.OaepSHA1; @@ -186,7 +186,9 @@ public void Rsa_Encrypt_LengthLimit_Test(RsaSize size) maxLength = (int) size / 8 - 42; //214 //40 rawData = rawStr.Substring(0, maxLength); - encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding); + Assert.Equal(decryptedStr, rawData); padding = RSAEncryptionPadding.OaepSHA256; @@ -194,19 +196,44 @@ public void Rsa_Encrypt_LengthLimit_Test(RsaSize size) maxLength = (int) size / 8 - 66; //190 //64 rawData = rawStr.Substring(0, maxLength); - encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + encryptedStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + decryptedStr = EncryptProvider.RSADecrypt(privateKey, encryptedStr, padding); + + Assert.Equal(decryptedStr, rawData); padding = RSAEncryptionPadding.OaepSHA384; - maxLength = (int) size / 8 - 100; //158 //96 + maxLength = (int) size / 8 - 98; //158 //96 rawData = rawStr.Substring(0, maxLength); - encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + 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); - encryptStr = EncryptProvider.RSAEncrypt(publicKey, rawData, padding); + 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(() => + { + EncryptProvider.RSAEncrypt(publicKey, rawStr); + }); } } } From 55f7da86736694249f358df10155fa265e38b066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=7E?= Date: Tue, 5 Jun 2018 12:30:14 +0800 Subject: [PATCH 3/3] update version to 2.0.7 --- src/NETCore.Encrypt/NETCore.Encrypt.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NETCore.Encrypt/NETCore.Encrypt.csproj b/src/NETCore.Encrypt/NETCore.Encrypt.csproj index 2243b91..e0a3680 100644 --- a/src/NETCore.Encrypt/NETCore.Encrypt.csproj +++ b/src/NETCore.Encrypt/NETCore.Encrypt.csproj @@ -7,16 +7,16 @@ Lvcc Lvcc NETCore encrypt and decrpty tool,Include AES,RSA,MD5,SAH1,SAH256,SHA384,SHA512 - Copyright 2017 (c) Lvcc. All rights reserved + Copyright 2018 (c) Lvcc. All rights reserved https://github.com/myloveCc/NETCore.Encrypt/blob/master/License https://github.com/myloveCc/NETCore.Encrypt https://github.com/myloveCc/NETCore.Encrypt Github - 2.0.6.0 - 2.0.6.0 - 2.0.6 - 1: Add demo about how to use. -2: Add new method for aes/des with byte[] encrypt/decrypt. + 2.0.7.0 + 2.0.7.0 + 2.0.7 + 1: Add OutofMaxlengthException for rsa encrypt. +2: Add test about rsa OutofMaxlengthException.