【发布时间】:2017-12-11 10:02:16
【问题描述】:
我有以下代码:
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
有人知道为什么会这样或者我该如何解决吗? (我不知道它是否来自我的加密方法,但我知道一个 Web 应用程序使用完全相同的东西来加密字符串并且它确实有效。)
编辑: 我用于手动加密的工具:3des
选项必须:
- 文本输入类型
- 纯文本输入文本
- 3DES 函数
- CBC 模式
- 固定键十六进制
- 固定初始向量
【问题讨论】:
-
您必须在此模式 (CBC) 下为此密码使用填充。
-
3DES是分组密码,在CBC模式下它只能加密8字节的倍数,如果你想用它来加密长度不是8字节的倍数的数据,那么您必须使用填充,但需要注意的是,您的加密数据可能比您的输入数据长最多 8 个字节。
-
不要在新工作中使用 3DES,它不如 AES 安全,并且只有 112 位安全性和三重密钥,而是使用 AES(高级加密标准)它支持 128,192 和 256 位的密钥大小。
-
你把你的字符串变成字节(好)把它变成十六进制(嗯?)再把它变成字节(?!)。那里的第二步和第三步可以被删除。但随后您尝试一次对一个角色执行 3DES。这真是太奇怪了。您想要 PKCS7 填充并将整个字节数组扔到
TransformFinalBlock。它会变成 ((inputBytes.Length + 15) / 8) * 8)` 字节。 (0 -> 8, 7 -> 8, 8 -> 16, 15 -> 16, 16 -> 24, 等等) -
这是我用于手动加密的工具 link ,该应用程序没有显示任何 Padding 选项,我的客户端使用此工具使用 PHP CI 语言进行加密。那么我应该如何修改我的代码并且结果可以与工具相同?选项必须是Plain Input Text、3des function、CBC mode、fixed Hex Key、fixed IV。
标签: c# encryption 3des tripledes