指定的填充模式对此算法无效 - .net Core [英] Specified padding mode is not valid for this algorithm - .net Core
问题描述
当我从 .net 4.5 转换为 .net core 2 时收到以下错误消息.代码完全相同.我看过一些帖子,但没有一个能解决这个错误.我正在使用 RijndaelManaged 加密.
I am getting the following error message when I convert from .net 4.5 to .net core 2. The code is exactly the same. I have seen a few posts but none have solve this error. I am using RijndaelManaged encryption.
Specified padding mode is not valid for this algorithm.
at Internal.Cryptography.UniversalCryptoDecryptor.DepadBlock(Byte[] block, Int32 offset, Int32 count)
at Internal.Cryptography.UniversalCryptoDecryptor.UncheckedTransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at Internal.Cryptography.UniversalCryptoTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.StreamReader.Dispose(Boolean disposing)
at System.IO.TextReader.Dispose()
以下是我正在使用的代码.我在以下位置收到错误:retval = srDecrypt.ReadToEnd();
Below is the code that I am using. I am getting the error at: retval = srDecrypt.ReadToEnd();
public static class EncryptionExtension
{
#region "Enumerations"
public enum EncryptionAlgorithms
{
Rijndael = 0
}
public enum CryptMethod
{
Encrypt = 0,
Decrypt = 1
}
#endregion
#region "Private Attributes"
private static byte[] CRYPT_SALT = {
99,
115,
120,
76,
105,
103,
105,
116
};
private static byte[] IV_8 = new byte[] {
2,
63,
9,
36,
235,
174,
78,
12
};
private static byte[] IV_16 = new byte[] {
15,
199,
56,
77,
244,
126,
107,
239,
9,
10,
88,
72,
24,
202,
31,
108
};
private static byte[] IV_24 = new byte[] {
37,
28,
19,
44,
25,
170,
122,
25,
25,
57,
127,
5,
22,
1,
66,
65,
14,
155,
224,
64,
9,
77,
18,
251
};
private static byte[] IV_32 = new byte[] {
133,
206,
56,
64,
110,
158,
132,
22,
99,
190,
35,
129,
101,
49,
204,
248,
251,
243,
13,
194,
160,
195,
89,
152,
149,
227,
245,
5,
218,
86,
161,
124
#endregion
};
#region "String Encryption"
public static string EncryptString(EncryptionAlgorithms Method, string Value, string Key)
{
return CryptString(CryptMethod.Encrypt, Method, Value, Key);
}
public static string DecryptString(EncryptionAlgorithms Method, string Value, string Key)
{
return CryptString(CryptMethod.Decrypt, Method, Value, Key);
}
public static string CryptString(CryptMethod Method, EncryptionAlgorithms Algorithm, string Value, string Key)
{
// Check arguments.
if (Value == null || Value.Length <= 0)
{
throw new ArgumentNullException("Data can not be empty");
}
if (Key == null || Key.Length <= 0)
{
throw new ArgumentNullException("Key can not be empty");
}
SymmetricAlgorithm provider = null;
string retval = null;
// Declare the stream used to encrypt to an in memory array of bytes.
MemoryStream msCrypt = null;
ICryptoTransform ICrypt = null;
try
{
// Create a Provider object
switch (Algorithm)
{
case EncryptionAlgorithms.Rijndael:
provider = new RijndaelManaged();
break;
}
provider.KeySize = provider.LegalKeySizes[0].MaxSize;
provider.BlockSize = provider.LegalBlockSizes[0].MaxSize;
provider.Key = DerivePassword(Key, provider.LegalKeySizes[0].MaxSize / 8);
switch (provider.BlockSize / 8)
{
case 8:
provider.IV = IV_8;
break;
case 16:
provider.IV = IV_16;
break;
case 24:
provider.IV = IV_24;
break;
case 32:
provider.IV = IV_32;
break;
}
if (Method == CryptMethod.Encrypt)
{
////encrypt value
//// Create a encryptor to perform the stream transform.
//ICrypt = provider.CreateEncryptor(provider.Key, provider.IV);
//// Create the streams used for encryption/decryption
//msCrypt = new MemoryStream();
//using (CryptoStream csEncrypt = new CryptoStream(msCrypt, ICrypt, CryptoStreamMode.Write))
//{
// using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
// {
// //Write all data to the stream.
// swEncrypt.Write(Value);
// }
//}
}
else
{
//decrypt value
//convert the ciphered text into a byte array
byte[] cipherBytes = null;
cipherBytes = System.Convert.FromBase64String(Value);
// Create a deccryptor to perform the stream transform.
ICrypt = provider.CreateDecryptor(provider.Key, provider.IV);
// Create the streams used for decryption.
msCrypt = new MemoryStream(cipherBytes);
using (CryptoStream csDecrypt = new CryptoStream(msCrypt, ICrypt, CryptoStreamMode.Write))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
//Read the decrypted bytes from the decrypting stream
// and place them in a string.
retval = srDecrypt.ReadToEnd();
}
}
}
}
catch (Exception ex)
{
//throw new AceExplorerException(ex.Message + " " + ex.StackTrace + " " + ex.TargetSite.ToString() + " " + ex.Source, ex.InnerException);
throw new Exception(ex.Message + " " + ex.StackTrace + " " + ex.TargetSite.ToString() + " " + ex.Source, ex.InnerException);
}
finally
{
// Clear the Provider object.
if ((provider != null))
{
provider.Clear();
}
}
if (Method == CryptMethod.Encrypt)
{
// Return the encrypted bytes from the memory stream.
return System.Convert.ToBase64String(msCrypt.ToArray());
}
else
{
// Return the unencrypted text
return retval;
}
}
#endregion
#region "Private Utility Functions"
private static byte[] DerivePassword(string Password, int Length)
{
Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(Password, CRYPT_SALT, 5);
return derivedBytes.GetBytes(Length);
}
#endregion
}
要运行它,您可以执行以下操作
The to run it you can do the following
var decryptedstring = EncryptionExtension.CryptString(EncryptionExtension.CryptMethod.Decrypt, EncryptionExtension.EncryptionAlgorithms.Rijndael, "[Encrypted String]", "[key]");
更新:我已经添加了完整的课程.抱歉我没有看到被屏蔽的部分
Update: I have added the full class. Sorry I didnt see the blocked out sections
更新 2:我将 PaddingMode 更改为 None.我不再看到错误.但现在返回值是: s) j U #V İ H?X
Update 2: I changed the PaddingMode to None. I no longer see the error. But now the return value is: �s)���j�U�#V���H?X�
更新 3:在 4.5 上调试代码时,我有:- PKCS7 中的填充- BlockSize = 256 vs 128 在核心我试了jimi的代码,却得到了奇怪的字符:寛Щ 챫蔧⽢쉈⩭」啌斪ᆈ锚ય杄我尝试使用以下方法修改它: Convert.ToBase64String(DecodedText);我没有奇怪的字符,但不是我期望的结果.
Update 3: When debugging the code on 4.5 I have: - Padding in PKCS7 - BlockSize = 256 vs 128 in Core I tried Jimi's code but got strange characters: 寛Щ�챫蔧⽢쉈⩭」啌斪ᆈ锚ય杄䕳 I tried modifying it by using the following: Convert.ToBase64String(DecodedText); I didn't have the strange characters but not the results I was expecting.
预期结果:
关键:DNACTSACEENGINE
Key: DNACTSACEENGINE
字符串:IdIFR+PP5yDggqgSlB0KfcNTG+DkRuRbPfeljJeGm+c=
string: IdIFR+PP5yDggqgSlB0KfcNTG+DkRuRbPfeljJeGm+c=
结果: !vbqZgZKbu4?8
results: !vbqZgZKbu4?8
更新.Net Core 不支持 256 的块大小
Update .Net Core doesnt support a blocksize of 256
提前致谢.任何帮助表示赞赏
Thanks in advance. Any help is appreciated
推荐答案
我已经修复了没有产生一致结果的部分.
I've fixed the part that did not produce a consistent result.
但是,由于加密方法在您的代码中被注释掉,我不确定加密输入值是否正是此处显示的值,还是来自不同的来源和/或不同的加密方法.
But, since the Encryption method is commented out in your code, I'm not sure whether the Encrypted input value is exactly what is presented here or it comes from a different source and/or a different method of Encryption.
我已将 MemoryStream
分配的字节数组(由加密和解密方法使用)与原始值的 Unicode
编码/解码集成.
当然可以使用另一种编码.(还使用 UTF8
进行了测试,这应该是默认设置).
该字符串照常使用 Base64Encoded/Decoded.
I've integrated the MemoryStream
assigned byte array, used by both the Encryption and the Decryption methods, with the Unicode
Encoding/Decoding of the original value.
Of course another Encoding can be used. (Tested also with UTF8
, which should be the default).
The string is Base64Encoded/Decoded as usual.
我在这里只发布 #region "String Encryption"
块中包含的代码部分.
其余代码保持不变.
I'm posting here just the section of code included in the #region "String Encryption"
block.
The rest of the code is untouched.
测试:Visual Studio pro 15.8.0
.Net 框架:Core 2.1
C# 6.0 和 C# 7.3
Ecryption/Decryption 方法是这样调用的:
The Ecryption/Decryption methods are called this way:
string encryptedstring = EncryptionExtension.CryptString(
EncryptionExtension.CryptMethod.Encrypt, EncryptionExtension.EncryptionAlgorithms.Rijndael,
"Some text to encrypt, more text to encrypt", "SomeKey");
string decryptedstring = EncryptionExtension.CryptString(
EncryptionExtension.CryptMethod.Decrypt, EncryptionExtension.EncryptionAlgorithms.Rijndael,
encryptedstring, "SomeKey");
<小时>
#region "String Encryption"
public static string EncryptString(EncryptionAlgorithms Method, string Value, string Key)
{
return CryptString(CryptMethod.Encrypt, Method, Value, Key);
}
public static string DecryptString(EncryptionAlgorithms Method, string Value, string Key)
{
return CryptString(CryptMethod.Decrypt, Method, Value, Key);
}
<小时>
public static string CryptString(CryptMethod Method, EncryptionAlgorithms Algorithm, string Value, string Key)
{
if (Value == null || Value.Length <= 0)
{
throw new ArgumentNullException("Data can not be empty");
}
if (Key == null || Key.Length <= 0)
{
throw new ArgumentNullException("Key can not be empty");
}
SymmetricAlgorithm provider = null;
try
{
switch (Algorithm)
{
case EncryptionAlgorithms.Rijndael:
provider = new RijndaelManaged();
break;
}
provider.KeySize = provider.LegalKeySizes[0].MaxSize;
provider.BlockSize = provider.LegalBlockSizes[0].MaxSize;
provider.Key = DerivePassword(Key, provider.LegalKeySizes[0].MaxSize / 8);
switch (provider.BlockSize / 8)
{
case 8:
provider.IV = IV_8;
break;
case 16:
provider.IV = IV_16;
break;
case 24:
provider.IV = IV_24;
break;
case 32:
provider.IV = IV_32;
break;
}
if (Method == CryptMethod.Encrypt)
{
byte[] encodedText = Encoding.Unicode.GetBytes(Value);
// Create the streams used for encryption/decryption
using (ICryptoTransform encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
using (var msCrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msCrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(encodedText, 0, encodedText.Length);
csEncrypt.FlushFinalBlock();
return Convert.ToBase64String(msCrypt.ToArray());
}
}
else
{
byte[] cipherBytes = Convert.FromBase64String(Value);
// Create the streams used for decryption.
using (ICryptoTransform decryptor = provider.CreateDecryptor(provider.Key, provider.IV))
using (var msCrypt = new MemoryStream(cipherBytes))
using (var csDecrypt = new CryptoStream(msCrypt, decryptor, CryptoStreamMode.Read))
{
byte[] decodedText = new byte[cipherBytes.Length];
int decryptedCount = csDecrypt.Read(decodedText, 0, decodedText.Length);
return Encoding.Unicode.GetString(decodedText, 0, decryptedCount);
}
}
}
catch (Exception ex)
{
//throw new AceExplorerException(ex.Message + " " + ex.StackTrace + " " + ex.TargetSite.ToString() + " " + ex.Source, ex.InnerException);
throw new Exception(ex.Message + " " + ex.StackTrace + " " + ex.TargetSite.ToString() + " " + ex.Source, ex.InnerException);
}
finally
{
// Clear the Provider object.
provider?.Clear();
}
}
#endregion
private static byte[] DerivePassword(string password, int length)
{
Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(password, CRYPT_SALT, 1000);
return derivedBytes.GetBytes(length);
}
这篇关于指定的填充模式对此算法无效 - .net Core的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!