【发布时间】:2017-10-03 21:54:03
【问题描述】:
我有一些 C# 代码用于使用 TripleDES 进行加密和解密。我已将其简化为发布的最小示例。
using System;
using System.Security;
using System.Security.Cryptography;
using System.IO;
using System.Text;
class TDes
{
static void Main() {
string key = "ABCDEF0123456789";
string iv = "ABCDEF01";
TDes tdes = new TDes(key, iv);
string dataToDecrypt = "x9iWzVc4FfU=";
string decrypted = tdes.Decrypt(dataToDecrypt,key);
Console.WriteLine(decrypted);
string dataToEncrypt = "abcdegf";
string encrypted = tdes.Encrypt(dataToEncrypt, key);
Console.WriteLine(encrypted);
}
public TripleDESCryptoServiceProvider TdesProvider;
public TDes(string Key, string IV)
{
TdesProvider = new TripleDESCryptoServiceProvider();
TdesProvider.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
TdesProvider.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV);
}
public string Decrypt(string Source, string Key)
{
long lLen;
int nRead, nReadTotal;
byte[] buf = new byte[3];
byte[] decData;
byte[] encData;
System.IO.MemoryStream sin;
System.IO.MemoryStream sout;
CryptoStream decStream;
encData = System.Convert.FromBase64String(Source);
sin = new MemoryStream(encData);
sout = new MemoryStream();
decStream = new CryptoStream(sin,
TdesProvider.CreateDecryptor(),
CryptoStreamMode.Read);
lLen = sin.Length;
nReadTotal = 0;
while (nReadTotal < lLen)
{
nRead = decStream.Read(buf, 0, buf.Length);
if (0 == nRead) break;
sout.Write(buf, 0, nRead);
nReadTotal += nRead;
}
decStream.Close();
decData = sout.ToArray();
ASCIIEncoding ascEnc = new ASCIIEncoding();
return ascEnc.GetString(decData);
}
public string Encrypt(string Source, string Key)
{
long lLen;
int nRead, nReadTotal;
byte[] buf = new byte[3];
byte[] srcData;
byte[] encData;
System.IO.MemoryStream sin;
System.IO.MemoryStream sout;
CryptoStream encStream;
srcData = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
sin = new MemoryStream();
sin.Write(srcData,0,srcData.Length);
sin.Position = 0;
sout = new MemoryStream();
encStream = new CryptoStream(sout,
TdesProvider.CreateEncryptor(),
CryptoStreamMode.Write);
lLen = sin.Length;
nReadTotal = 0;
while (nReadTotal < lLen)
{
nRead = sin.Read(buf, 0, buf.Length);
encStream.Write(buf, 0, nRead);
nReadTotal += nRead;
}
encStream.Close();
encData = sout.ToArray();
return System.Convert.ToBase64String(encData);
}
}
这是可行的(从某种意义上说,它可以解密使用相同的密钥和 iv 加密的内容)。但是,我一直未能在 openssl 中提出等价物。我最近尝试过的事情:
echo abcdefg | openssl enc -e -des-ede3-cbc -a -k ABCDEF0123456789 -iv ABCDEF01
U2FsdGVkX1+o9K0itpYTEqGfyMjN8gARTYIDB2ZHg1U=
C# 代码产生了一个非常不同的结果 x9iWzVc4FfU= 同样,如果我将 x9iWzVc4FfU= 输入到反向 openssl 命令它 barfs。
我正在为此而烦恼。 c# 代码是不可更改的。需要openssl,因为我使用的是php。
【问题讨论】:
-
请勿将 3DES 用于新工作,它已被 AES 取代。此外,在这个问题中,正在使用双密钥 3DES,它非常不安全,只有 112 位密钥,并且仅比 DES 强四倍。对于现有工作,最好努力更新到 AES。
-
我知道这个@zaph。谢谢,但我无法控制它。在这一点上只需要拔出它来适应它。
-
请出示您的基于 C 的 OpenSSL 代码。否则,这个问题只是要求提供所有代码或教程。
-
是的,安全并不是那么重要,通常似乎有理由忽略它,对吧?到 2050 年我们还会有 2-key 3DES,可能仍然有同样的借口。为什么这段代码可能会被引用为不更新对方代码的原因,一个永无止境的循环!解决方案,只需添加一个版本标签,同时添加旧版本和安全版本,然后双方可以分别及时更新,最终会有安全加密。它只需要一个 1 字节的版本指示符。它是允许 HTTP/SSL/TLS 更新和向后兼容的版本控制。
-
@zaph 你误读了我的评论吗?我说过我没有可以控制它。
标签: c# php encryption openssl 3des