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存储在某个地方,这就是我假设这个答案打算让你做的(但没有明确显示)