加密数据的长度是无效的 [英] Length of the data to Encrypt is invalid

查看:185
本文介绍了加密数据的长度是无效的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

获取异常数据的长度,加密是无效的。

 私有静态只读的byte [] =盐Encoding.ASCII.GetBytes(S @ SH @克拉@ VMS); 

公共静态字符串加密(字符串textToEncrypt,串encryptionPassword)
{
的byte [] encryptedBytes = NULL;

{
变种算法=信息getAlgorithm(encryptionPassword);
algorithm.Padding = PaddingMode.None;使用(ICryptoTransform的加密= algorithm.CreateEncryptor(algorithm.Key,algorithm.IV))
{
字节[] = bytesToEncrypt Encoding.UTF8.GetBytes(textToEncrypt)
;
encryptedBytes = InMemoryCrypt(bytesToEncrypt,加密);
}
}
赶上(异常前)
{
MessageBox.Show(ex.Message);
}
返回Convert.ToBase64String(encryptedBytes);
}

//执行在内存中的加密/解密的字节数组上的转变。

私人静态的byte [] InMemoryCrypt(字节[]数据,ICryptoTransform的变换)
{
MemoryStream的内存=新的MemoryStream();使用(流流=新的CryptoStream(存储,转换,CryptoStreamMode.Write))
{
stream.Flush()
;
stream.Write(数据,0,data.Length);
//stream.FlushFinalBlock();
}
返回memory.ToArray();
}

私有静态RijndaelManaged的信息getAlgorithm(字符串encryptionPassword)
{
//创建一个从encryptionPassword和盐的加密密钥。
VAR键=新Rfc2898DeriveBytes(encryptionPassword,盐);
//声明,我们将使用Rijndael算法与我们刚刚拿到了钥匙。
变种算法=新RijndaelManaged的();
INT bytesForKey = algorithm.KeySize / 8;
INT bytesForIV = algorithm.BlockSize / 8;
algorithm.Key = key.GetBytes(bytesForKey);
algorithm.IV = key.GetBytes(bytesForIV);
返回算法;
}

和解密程序是:



 公共静态字符串解密(字符串encryptedText,串encryptionPassword)
{
变种算法=信息getAlgorithm(encryptionPassword);
algorithm.Padding = PaddingMode.PKCS7;
字节[] descryptedBytes;使用(ICryptoTransform的解密= algorithm.CreateDecryptor(algorithm.Key,algorithm.IV))
{
字节[] = encryptedBytes Convert.FromBase64String(encryptedText)
;
descryptedBytes = InMemoryCrypt(encryptedBytes,解密);
}
返回Encoding.UTF8.GetString(descryptedBytes);
}


解决方案

PaddingMode.None 要求输入是块的大小的倍数。使用somethink像 PaddingMode.PKCS7 instread。






其他几个与您的代码的问题:




  1. 一个常数不使一个很好的盐

  2. 恒盐从密码IV确定性推导在一起意味着你重用(密钥,IV)对,不应该做

  3. 您不添加认证/某种形式的MAC 。这往往导致填充神谕或类似的攻击

  4. 您了解更多从PBKDF2输出原始容量。那你的一半密钥派生的速度没有放慢攻击者。


Getting Exception " length of the data to ENCRYPTION is invalid".

private static readonly byte[] salt = Encoding.ASCII.GetBytes("S@sh@kt@ VMS");

public static string Encrypt(string textToEncrypt, string encryptionPassword)
{
    byte[] encryptedBytes = null;
    try
    {
        var algorithm = GetAlgorithm(encryptionPassword);
        algorithm.Padding = PaddingMode.None;
        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV))
        {
            byte[] bytesToEncrypt = Encoding.UTF8.GetBytes(textToEncrypt);
            encryptedBytes = InMemoryCrypt(bytesToEncrypt, encryptor);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return Convert.ToBase64String(encryptedBytes);
}

 // Performs an in-memory encrypt/decrypt transformation on a byte array.

private static byte[] InMemoryCrypt(byte[] data, ICryptoTransform transform)
{
    MemoryStream memory = new MemoryStream();
    using (Stream stream = new CryptoStream(memory, transform, CryptoStreamMode.Write))
    {
        stream.Flush();
        stream.Write(data, 0, data.Length);
        //stream.FlushFinalBlock();
    }
    return memory.ToArray();
}

private static RijndaelManaged GetAlgorithm(string encryptionPassword)
{
    // Create an encryption key from the encryptionPassword and salt.
    var key = new Rfc2898DeriveBytes(encryptionPassword, salt);
    // Declare that we are going to use the Rijndael algorithm with the key that we've just got.
    var algorithm = new RijndaelManaged();
    int bytesForKey = algorithm.KeySize/8;
    int bytesForIV = algorithm.BlockSize/8;
    algorithm.Key = key.GetBytes(bytesForKey);
    algorithm.IV = key.GetBytes(bytesForIV);
    return algorithm;
}

And the decryption routine is:

public static string Decrypt(string encryptedText, string encryptionPassword)
{
    var algorithm = GetAlgorithm(encryptionPassword);
    algorithm.Padding = PaddingMode.PKCS7; 
    byte[] descryptedBytes;
    using (ICryptoTransform decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV))
    {
        byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
        descryptedBytes = InMemoryCrypt(encryptedBytes, decryptor);
    } 
    return Encoding.UTF8.GetString(descryptedBytes); 
} 

解决方案

PaddingMode.None requires that the input is a multiple of the block size. Use somethink like PaddingMode.PKCS7 instread.


A few other issues with your code:

  1. A constant doesn't make a good salt
  2. The constant salt together with deterministic derivation of the IV from the password means that you're reusing (Key, IV) pairs, which should not be done
  3. You don't add authentication/some kind of MAC. That often leads to padding oracles or similar attacks
  4. You read more the native size from the PBKDF2 output. That halves your key derivation speed without slowing down an attacker.

这篇关于加密数据的长度是无效的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆