У меня есть код 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.
Есть несколько вещей:
Опечатка. В вашем C # вы шифруете «abcdegf», в вашем OpenSSL вы используете «abcdefg» (обратите внимание на порядок f
а также g
).
echo
добавляет новую строку к тому, что он выводит. использование echo -n
чтобы получить тот же результат, что и ваш код (убедитесь, что ваш echo
на самом деле имеет -n
вариант или использовать printf
при шифровании).
Вы хотите опция командной строки -K
скорее, чем -k
. -k
указывает пароль который вводится через функцию KDF, вы хотите указать ключ напрямую.
Ваш код C # использует байты ASCII ключа и строки IV. Командная строка OpenSSL интерпретирует их как шестнадцатеричные строки. То, что вы хотите использовать в командной строке 41424344454630313233343536373839
для ключа (шестнадцатеричное кодирование байтов, составляющих «ABCDEF0123456789») и 4142434445463031
для IV (шестнадцатеричное кодирование «ABCDEF01»).
Ваш ключ длиной 16 байт. Это означает, что Код C # использует «2 ключа» 3DES. В OpenSSL вам нужно явно указать это des-ede-cbc
(обратите внимание на отсутствие 3
).
Таким образом, комбинируя все это, для репликации того, что делает ваш код C #, вам нужно что-то вроде этого:
$ echo -n abcdegf | openssl enc -e -des-ede-cbc -a -K 41424344454630313233343536373839 -iv 4142434445463031
x9iWzVc4FfU=
Других решений пока нет …