C# 指定的密钥不是此算法的有效大小
我已使用此代码:C# 指定的密钥不是此算法的有效大小,c#,encryption,rijndaelmanaged,C#,Encryption,Rijndaelmanaged,我已使用此代码: RijndaelManaged rijndaelCipher = new RijndaelManaged(); // Set key and IV rijndaelCipher.Key = Convert.FromBase64String("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912"); rijndaelCipher.
RijndaelManaged rijndaelCipher = new RijndaelManaged();
// Set key and IV
rijndaelCipher.Key = Convert.FromBase64String("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678912");
rijndaelCipher.IV = Convert.FromBase64String("1234567890123456789012345678901234567890123456789012345678901234");
我被扔了:
Specified key is not a valid size for this algorithm.
Specified initialization vector (IV) does not match the block size for this algorithm.
这根弦怎么了?我可以在一些示例中计算您的字符串吗?RijndaelManaged算法支持128、192或256位的密钥长度。您的密钥是这些大小之一吗?当base64解码时,字符串“abcdefghijklmnopqrstuvxyzabefghijklmnopqrstuvxyzo12345678912”产生48字节(384位)。RijndaelManaged支持128、192和256位密钥 有效的128位密钥是
newbyte[]{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F}
或者如果需要从base64获取它:转换.FromBase64String(“aaecawqffgcicqolda0odw=”
)
默认块大小为128位,因此相同的字节数组将与IV相同。使用随机数生成器类(RNGCryptoServiceProvider)使用随机字节填充指定的缓冲区,如下所示:
var numberOfBits = 256; // or 192 or 128, however using a larger bit size renders the encrypted data harder to decipher
var ivBytes = new byte[numberOfBits / 8]; // 8 bits per byte
new RNGCryptoServiceProvider().GetBytes(ivBytes);
var rijndaelManagedCipher = new RijndaelManaged();
//Don't forget to set the explicitly set the block size for the IV if you're not using the default of 128
rijndaelManagedCipher.BlockSize = 256;
rijndaelManagedCipher.IV = ivBytes;
注意:同样的过程也可用于派生密钥。希望这有帮助。我不知道rijndaelCipher.Key的长度 如果是24,则rijndaelCipher.Key=s.SubString(0,24)
太简单了。这是我创建的类
public class ByteCipher
{
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private int _Keysize = (int)GlobalConfiguration.DataEncode_Key_Size;
private byte[] saltStringBytes;
private byte[] ivStringBytes;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
private string _passPhrase = GlobalConfiguration.DataEncode_Key;
private const string salt128 = "kljsdkkdlo4454GG";
private const string salt256 = "kljsdkkdlo4454GG00155sajuklmbkdl";
public ByteCipher(string passPhrase = null, DataCipherKeySize keySize = DataCipherKeySize.Key_128)
{
if (!string.IsNullOrEmpty(passPhrase?.Trim()))
_passPhrase = passPhrase;
_Keysize = keySize == DataCipherKeySize.Key_256 ? 256 : 128;
saltStringBytes = _Keysize == 256 ? Encoding.UTF8.GetBytes(salt256) : Encoding.UTF8.GetBytes(salt128);
ivStringBytes = _Keysize == 256 ? Encoding.UTF8.GetBytes("SSljsdkkdlo4454Maakikjhsd55GaRTP") : Encoding.UTF8.GetBytes("SSljsdkkdlo4454M");
}
public byte[] Encrypt(byte[] plainTextBytes)
{
if (plainTextBytes.Length <= 0)
return plainTextBytes;
using (var password = new Rfc2898DeriveBytes(_passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(_Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = _Keysize;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
return cipherTextBytes;
}
}
}
}
}
}
public byte[] Decrypt(byte[] cipherTextBytesWithSaltAndIv)
{
if (cipherTextBytesWithSaltAndIv.Length <= 0)
return cipherTextBytesWithSaltAndIv;
var v = Encoding.UTF8.GetString(cipherTextBytesWithSaltAndIv.Take(_Keysize / 8).ToArray());
if (v != salt256 && v != salt128)
return cipherTextBytesWithSaltAndIv;
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((_Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((_Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(_passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(_Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
symmetricKey.BlockSize = _Keysize;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return plainTextBytes;
}
}
}
}
}
}
}
公共类字节密码
{
//该常数用于确定加密算法的密钥大小(以位为单位)。
//我们在下面的代码中将其除以8,得到等效的字节数。
private int _Keysize=(int)GlobalConfiguration.DataEncode_Key_Size;
私有字节[]saltStringBytes;
私有字节[]ivStringBytes;
//此常量确定密码字节生成函数的迭代次数。
私有常量派生=1000;
私有字符串_passPhrase=GlobalConfiguration.DataEncode_密钥;
private const string salt128=“kljsdkkdlo4454GG”;
私有常量字符串salt256=“kljsdkkdlo4454GG00155sajuklmbkdl”;
公共字节密码(字符串密码短语=null,DataCipherKeySize-keySize=DataCipherKeySize.Key_128)
{
如果(!string.IsNullOrEmpty(passPhrase?.Trim()))
_密码短语=密码短语;
_Keysize=Keysize==DataCipherKeySize.Key_256?256:128;
saltStringBytes=\u Keysize==256?Encoding.UTF8.GetBytes(salt256):Encoding.UTF8.GetBytes(salt128);
ivStringBytes=_Keysize==256?Encoding.UTF8.GetBytes(“SSljsdkkdlo4454Maakikjhsd55GaRTP”):Encoding.UTF8.GetBytes(“SSljsdkkdlo4454M”);
}
公共字节[]加密(字节[]明文字节)
{
如果(plainTextBytes.Length我不明白:/my string to encode的长度为40-200有趣的巧合…这与我所有加密算法使用的密钥相同…实际上,它似乎支持,但这是因为有一个bug。只是不要忘了在单元测试期间解决这个bug。如果你使用随机数生成一个用于e的密钥加密一个密码,你怎么能稍后回来(生成一个不同的随机密钥)并确认密码是正确的?@jp2code这实际上是一个非常好的安全解决方案,只要你将ivBytes存储在某个地方,这就是我假设这个答案打算让你做的(但没有明确显示)