TripleDES要加密的数据长度无效

时间:2017-12-11 10:02:17

标签: c# encryption 3des tripledes

我有以下代码:

public static string Encrypt3Des(string cipherString)
{
    string result = "";

    byte[] keyArray;
    byte[] ivArray;

    byte[] toEncryptArray = Enc3DesPerChar(cipherString);
    //string toEncryptString = ByteArrayToString(toEncryptArray);

    // Get the key from config file
    System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
    string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
    string iv = (string)settingsReader.GetValue("InitializationVector", typeof(String));

    keyArray = StringToByteArray(key);
    ivArray = StringToByteArray(iv);

    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    //set the secret key for the tripleDES algorithm

    tdes.Key = keyArray;
    tdes.IV = ivArray;

    //ChiperMode
    tdes.Mode = CipherMode.CBC;

    //PaddingMode(if any extra byte added)
    tdes.Padding = PaddingMode.None;

    ICryptoTransform cTransform = tdes.CreateEncryptor();
    //transform the specified region of bytes array to resultArray
    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

    //Release resources held by TripleDes Encryptor
    tdes.Clear();

    result = ByteArrayToString(resultArray);

    return result;
}

这是我的方法:

protected static string ByteArrayToString(byte[] ba)
{
    StringBuilder hex = new StringBuilder(ba.Length * 2);
    foreach (byte b in ba)
        hex.AppendFormat("{0:x2}", b);
    return hex.ToString();
}

protected static byte[] StringToByteArray(String hex)
{
    int NumberChars = hex.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    return bytes;
}

protected static byte[] Enc3DesPerChar(String toEncrypt)
{
    string toAsciiString = ByteArrayToString(Encoding.ASCII.GetBytes(toEncrypt));

    string toRoll = toAsciiString;

    int NumberChars = toRoll.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
    {
        bytes[i / 2] = Convert.ToByte(toRoll.Substring(i, 2), 16);
    }
    return bytes;
}

使用上述方法一切正常,直到我发现该方法不能接受少于8个字符。

引发错误的块代码:

byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

错误讯息:

  

要加密的数据长度无效。

示例输入:

Encrypt3Des("14022000"); // return encrypt because 8 character or more

Encrypt3Des("1402200"); // return error because 7 character

有人知道这是为什么或我如何解决它? (我不知道它是否来自我的加密方法,但我知道一个网络应用程序使用完全相同的东西加密字符串,并且确实有效。)

编辑: 我用于手动加密的工具:3des

选项必须:

  • 文字输入类型
  • 明文输入文字
  • 3DES功能
  • CBC模式
  • 固定键十六进制
  • 修正了初始向量

2 个答案:

答案 0 :(得分:1)

您使用填充为无。将填充模式设置为PKCS7

答案 1 :(得分:-1)

好吧,我想刚刚找到了解决方案(我的客户告诉我怎么做),我需要在循环之前用null填充字符。 null可以使用&#34; 00&#34;转换为ascii。所以我决定使用&#39; 0&#39;来决定PadRight到ascii的结果到16个字符,所以我的方法之一变成:

protected static byte[] Enc3DesPerChar(String toEncrypt)
{
    string toAsciiString = ByteArrayToString(Encoding.ASCII.GetBytes(toEncrypt));

    string toRoll = toAsciiString.PadRight(16,'0');

    int NumberChars = toRoll.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
    {
        bytes[i / 2] = Convert.ToByte(toRoll.Substring(i, 2), 16);
    }
    return bytes;
}