将 OpenSSL 加密转换为原生 C#

Convert OpenSSL encryption into native C#

我有一个遗留应用程序,它使用 OpenSSL 使用 DES3.

加密字符串

这些是为 OpenSSL 设置的参数:

OpenSSL enc -des3 -nosalt -a -A -iv 1234567890123456 -K 1234567890123456...48

密钥是 48 位数字 字符串 并且 iv 是前 16 位数字的子字符串 这个键。

现在,我正在尝试使用 C# 的 System.Cryptography 库复制此功能,并且尽可能不使用 OpenSSL。

我的目标是不必使用 OpenSSL 并在本机 C# 代码中完成加密。

这是我目前得到的:

public string Encrypt(string toEncrypt, bool useHashing)
{
    var _key = "48...digits...";
    byte[] keyArray;
    var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);

    if (useHashing)
    {
        var hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_key));

        hashmd5.Clear();
    }
    else
    {
        keyArray = Encoding.UTF8.GetBytes(_key);
    }

    var tdes = new TripleDESCryptoServiceProvider();

    tdes.Key = keyArray;

    // Is this even the correct cipher mode?
    tdes.Mode = CipherMode.CBC;

    // Should the PaddingMode be None?
    tdes.Padding = PaddingMode.PKCS7;

    // THIS is the line where I am currently stuck on:
    tdes.IV = Encoding.UTF8.GetBytes(_key.Substring(0, 16));

    var cTransform = tdes.CreateEncryptor();

    var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

正如代码中的注释所写,我不太确定我是否使用了正确的密码,甚至可能填充模式不正确并且我的 iv 的长度为 16 bytes 但只有 8 bytes 是预期的。

此外,我确实已经尝试了我的运气,无论是否对 key/iv 进行哈希处理。

甚至可以将上述 OpenSSL 逻辑转换为纯 C# 吗?

密钥和 IV 必须为 openssl enc 指定 -K-iv 作为 十六进制 值。这在 C# 代码中缺失,因此本质上是以下表达式

tdes.Key = Encoding.UTF8.GetBytes(_key);
tdes.IV = Encoding.UTF8.GetBytes(_key.Substring(0, 16));

必须替换为

tdes.Key = StringToByteArray(_key);
tdes.IV = StringToByteArray(_key.Substring(0, 16));

useHashing == false生成相同的密文。这里的StringToByteArray是一个将十六进制字符串转换成对应字节数组的方法,例如here.

还需要注意的是,.NET 不接受太 weak 的密钥,例如:

123456789012345612345678901234561234567890123456

如果是这样的密钥,则会抛出 CryptographicException指定的密钥是 'TripleDES' 的已知弱密钥,无法使用 )。 OpenSSL 接受此密钥。

关于安全:

  • 现在不应该使用 MD5 来生成密钥,更多 here
  • 此外,MD5 生成一个 16 字节的散列。因此,总是使用键控选项 2,它弱于键控选项 1 (Keying options)。
  • 一般使用密钥作为IV是不安全的,更多here.
  • 与今天的标准 AES 相比,TripleDES 更慢 here