Rijndael算法填充错误 [英] Rijndael Padding Error

查看:298
本文介绍了Rijndael算法填充错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我想加密/解密通过Rijaendal的字符串。
我根本无法弄清楚,为什么解密炸毁。我总是最后使用不正确的填充错误。抛出我送行的一件事是我的加密,我回来作为HEX阵列的结果。它具有14字节的长度。在我的解密功能,相同的字节数组结束有在从十六进制转换为16字节



任何帮助,将不胜感激:

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;

命名空间rjandal
{
类节目
{
静态无效的主要(字串[] args)
{
串DataForEncrypting =这是一个测试;

串键=的String.Empty;
串IV =的String.Empty;

使用(RMT System.Security.Cryptography.RijndaelManaged =新System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rmt.GenerateKey();
rmt.GenerateIV();
键= Convert.ToBase64String(rmt.Key);
IV = Convert.ToBase64String(rmt.IV);
}

字符串的EncryptedData = _encrypt(DataForEncrypting,钥匙,IV);
串unencryptedData = _decrypt(钥匙,四,HexString2Ascii(的EncryptedData));

Console.WriteLine(unencryptedData);
Console.WriteLine(的EncryptedData);
Console.ReadKey();
}

私人静态字符串_encrypt(字符串值,字符串键,字符串initVector)
{
字节[]缓冲= ASCIIEncoding.ASCII.GetBytes(值);
字节[] encBuffer;使用
(RMT System.Security.Cryptography.RijndaelManaged =新System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
encBuffer = rmt.CreateEncryptor(Convert.FromBase64String(键),
Convert.FromBase64String(initVector))TransformFinalBlock(缓冲,0,buffer.Length)。
}
串encryptValue = ConvertToHex(ASCIIEncoding.ASCII.GetString(encBuffer));
返回encryptValue;
}

私人静态字符串_decrypt(字符串键,字符串initVector,字符串值)
{
字节[] = hexBuffer ASCIIEncoding.ASCII.GetBytes(值);
字节[] decBuffer;使用
(RMT System.Security.Cryptography.RijndaelManaged =新System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
decBuffer = rmt.CreateDecryptor(Convert.FromBase64String(键),
Convert.FromBase64String(initVector))TransformFinalBlock(hexBuffer,0,hexBuffer.Length)。
}

返回System.Text.ASCIIEncoding.ASCII.GetString(decBuffer);
}

私人静态字符串ConvertToHex(字符串asciiString)
{
十六进制字符串=;
的foreach(在asciiString焦三)
{
INT TMP = C;
六角+ =的String.Format({0:X2}(UINT)System.Convert.ToUInt32(tmp.ToString()));
}
返回十六进制;
}

私人静态字符串HexString2Ascii(字符串十六进制串)
{
StringBuilder的SB =新的StringBuilder();
的for(int i = 0; I< = hexString.Length - 2; I + = 2)
{
sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse (hexString.Substring(I,2),System.Globalization.NumberStyles.HexNumber))));
}
返回sb.ToString();
}

}
}


解决方案

您不应该使用ASCII字符编码作为一个中间步骤;你应该改变你的职责,从十六进制到ASCII(和回来)从字节[] 赴十六进制(和回来)来代替。

 私有静态字符串ConvertToHex(字节[]数据)
{
十六进制字符串=;
的foreach(在数据字节B)
{
六角+ = b.ToString(X2);
}
返回十六进制;
}

私人静态的byte [] HexString2ByteArray(字符串十六进制串)
{
字节[] =输出新字节[hexString.Length / 2];

的for(int i = 0; I< = hexString.Length - 2; I + = 2)
{
输出[I / 2] = Convert.ToByte( hexString.Substring(I,2),16);
}
返回输出;
}



作为一个方面说明,有没有你正在寻找一个理由数组与一些更喜欢紧凑的Base64的十六进制表示?您使用的Base64在你的榜样传输的密钥和IV,所以我只是好奇是什么让你想返回加密的数据为十六进制这里。



在任何情况下,这里的东西应该为你工作:

 私有静态字符串_encrypt(字符串值,字符串键,字符串initVector) 
{
字节[]缓冲= Encoding.Unicode.GetBytes(值);
字节[] encBuffer;使用
(RMT System.Security.Cryptography.RijndaelManaged =新System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
encBuffer = rmt.CreateEncryptor(Convert.FromBase64String(键),
Convert.FromBase64String(initVector))TransformFinalBlock(缓冲,0,buffer.Length)。
}
串encryptValue = ConvertToHex(encBuffer);
返回encryptValue;
}

私人静态字符串_decrypt(字符串键,字符串initVector,字符串值)
{
字节[] = hexBuffer HexString2ByteArray(值);
字节[] decBuffer;使用
(RMT System.Security.Cryptography.RijndaelManaged =新System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
decBuffer = rmt.CreateDecryptor(Convert.FromBase64String(键),
Convert.FromBase64String(initVector))TransformFinalBlock(hexBuffer,0,hexBuffer.Length)。
}

返回Encoding.Unicode.GetString(decBuffer);
}


Hello I am trying to encrypt / decrypt a string via Rijaendal. I simply can't figure out why the decryption blows up. I always end up with an incorrect padding error. One thing that throws me off is the result of my encryption which I return as HEX array. It has a length of 14 bytes. In my decryption function, the same byte array ends up having 16 bytes upon conversion from HEX.

Any help would be appreciated:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace rjandal
{
    class Program
    {
        static void Main(string[] args)
        {
            string DataForEncrypting = "this is a test";

            string key = string.Empty;
            string iv = string.Empty;

            using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
            {
                rmt.KeySize = 256;
                rmt.BlockSize = 128;
                rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
                rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
                rmt.GenerateKey();
                rmt.GenerateIV();
                key = Convert.ToBase64String(rmt.Key);
                iv = Convert.ToBase64String(rmt.IV);
            }

            string encryptedData = _encrypt(DataForEncrypting, key, iv);
            string unencryptedData = _decrypt(key, iv, HexString2Ascii(encryptedData));

            Console.WriteLine(unencryptedData);
            Console.WriteLine(encryptedData);
            Console.ReadKey();
        }

        private static string _encrypt(string value, string key, string initVector)
        {
            byte[] buffer = ASCIIEncoding.ASCII.GetBytes(value);
            byte[] encBuffer;
            using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
            {
                rmt.KeySize = 256;
                rmt.BlockSize = 128;
                rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
                rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
                encBuffer = rmt.CreateEncryptor(Convert.FromBase64String(key),
                    Convert.FromBase64String(initVector)).TransformFinalBlock(buffer, 0, buffer.Length);
            }
            string encryptValue = ConvertToHex(ASCIIEncoding.ASCII.GetString(encBuffer));
            return encryptValue;
        }

        private static string _decrypt(string key, string initVector, string value)
        {
            byte[] hexBuffer = ASCIIEncoding.ASCII.GetBytes(value);
            byte[] decBuffer;
            using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
            {
                rmt.KeySize = 256;
                rmt.BlockSize = 128;
                rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
                rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
                decBuffer = rmt.CreateDecryptor(Convert.FromBase64String(key),
                    Convert.FromBase64String(initVector)).TransformFinalBlock(hexBuffer, 0, hexBuffer.Length);
            }

            return System.Text.ASCIIEncoding.ASCII.GetString(decBuffer);
        } 

        private static string ConvertToHex(string asciiString)
        {
            string hex = "";
            foreach (char c in asciiString)
            {
                int tmp = c;
                hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
            }
            return hex;
        }

        private static string HexString2Ascii(string hexString)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i <= hexString.Length - 2; i += 2)
            {
                sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber))));
            }
            return sb.ToString();
        }

    }
}

解决方案

You shouldn't be using ASCII character encoding as an intermediate step; you should change your functions that go from hex to ASCII (and back again) to go from a byte[] to hex (and back again) instead.

    private static string ConvertToHex(byte[] data)
    {
        string hex = "";
        foreach (byte b in data)
        {
            hex += b.ToString("X2");
        }
        return hex;
    }

    private static byte[] HexString2ByteArray(string hexString)
    {
        byte[] output = new byte[hexString.Length / 2];

        for (int i = 0; i <= hexString.Length - 2; i += 2)
        {
             output[i/2] = Convert.ToByte(hexString.Substring(i, 2), 16);
        }
        return output;
    }

As a side note, is there a reason that you're looking for a hex representation of the array versus something more compact like Base64? You're using Base64 in your example to transfer the key and IV, so I'm just curious about what makes you want to return the encrypted data as hex here.

In any case, here's something that should work for you:

    private static string _encrypt(string value, string key, string initVector)
    {
        byte[] buffer = Encoding.Unicode.GetBytes(value);
        byte[] encBuffer;
        using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
        {
            rmt.KeySize = 256;
            rmt.BlockSize = 128;
            rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
            rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
            encBuffer = rmt.CreateEncryptor(Convert.FromBase64String(key),
                Convert.FromBase64String(initVector)).TransformFinalBlock(buffer, 0, buffer.Length);
        }
        string encryptValue = ConvertToHex(encBuffer);
        return encryptValue;
    }

    private static string _decrypt(string key, string initVector, string value)
    {
        byte[] hexBuffer = HexString2ByteArray(value);
        byte[] decBuffer;
        using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
        {
            rmt.KeySize = 256;
            rmt.BlockSize = 128;
            rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
            rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
            decBuffer = rmt.CreateDecryptor(Convert.FromBase64String(key),
                Convert.FromBase64String(initVector)).TransformFinalBlock(hexBuffer, 0, hexBuffer.Length);
        }

        return Encoding.Unicode.GetString(decBuffer);
    } 

这篇关于Rijndael算法填充错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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