【问题标题】:TripleDES Encryption between PHP vs C#/.NETPHP 与 C#/.NET 之间的 TripleDES 加密
【发布时间】:2019-12-17 16:49:30
【问题描述】:

我有旧版服务器在 .NET/C# 中使用 TripleDES 加密。

需要使用 PHP 解密文本。

我编写了 PHP 代码,但它无法解密从 C# 生成的消息。

C#代码

using System;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Text;


namespace testns
{
    class Program
    {
        static void Main(string[] args)
        {
            string key = "123456789012345678901234";
            string iv = "12345678";

            string text = "this is just test string";
            string e = Program.EncryptTripleDES(text, key, iv);
            Console.WriteLine(e);

            string d = Program.DecryptTripleDES(e, key, iv);
            Console.WriteLine(d);

            // Return
            // QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZ
            // this is just test string
        }

        private static string EncryptTripleDES(string neqs, string nafKeyCode, string nafIvCode)
        {

            byte[] rgbKey = Encoding.UTF8.GetBytes(nafKeyCode);
            byte[] rgbIV = Encoding.UTF8.GetBytes(nafIvCode);

            string sEncrypted = string.Empty;

            if (!String.IsNullOrEmpty(neqs))
            {
                TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
                cryptoProvider.Mode = CipherMode.CBC;
                cryptoProvider.Padding = PaddingMode.None;

                byte[] buffer = Encoding.UTF8.GetBytes(neqs);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cs.Write(buffer, 0, buffer.Length);
                cs.FlushFinalBlock();

                sEncrypted = Convert.ToBase64String(ms.ToArray());

            }

            return sEncrypted;
        }

        private static string DecryptTripleDES(string neqs, string nafKeyCode, string nafIvCode)
        {

            byte[] rgbKey = Encoding.UTF8.GetBytes(nafKeyCode);
            byte[] rgbIV = Encoding.UTF8.GetBytes(nafIvCode);

            string decryptedText = string.Empty;

            if (!String.IsNullOrEmpty(neqs))
            {
                TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
                cryptoProvider.Mode = CipherMode.CBC;
                cryptoProvider.Padding = PaddingMode.None;
                byte[] buffer = Convert.FromBase64String(neqs);
                MemoryStream ms = new MemoryStream(buffer);
                CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cs);
                decryptedText = sr.ReadToEnd();

                //(new Logs()).LogException(decryptedText);
            }

            return decryptedText;
        }
    }
}

PHP 代码

$key = '123456789012345678901234';
$iv  = '12345678';
$text = 'this is just test string';

$e = openssl_encrypt($text, 'des-ede3-cbc', $key, 0, $iv);
echo $e . "<br /><br />";

$d = openssl_decrypt($e, 'des-ede3-cbc', $key, 0, $iv);
echo $d . "<br /><br />";

// Return
// QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZqN3DpVbYFwk=
// this is just test string

从 PHP 获得

QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZqN3DpVbYFwk=

来自 C#

QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZ

正如您所见,PHP 几乎相同,有额外的 qN3DpVbYFwk= 字符。

我做错了什么?和padding有关吗?

谢谢

【问题讨论】:

    标签: c# php .net 3des tripledes


    【解决方案1】:

    问题似乎是您在 C# 代码中关闭了填充 (PaddingMode.None) 并且在您的 PHP 代码中打开了填充(默认情况下)。

    当您将 0 作为选项参数传递时,OpenSSL 库方法 openssl_encryptopenssl_decrypt 默认打开填充。默认填充为PKCS#7

    因此,要解决您的问题,您需要将 PaddingMode.PKCS7 添加到您的 C# 代码中(我个人建议这样做):

    cryptoProvider.Padding = PaddingMode.PKCS7;
    

    或者在 PHP 中使用 OPENSSL_ZERO_PADDING 关闭填充。请记住,在 PHP 中,您需要将标志 OPENSSL_ZERO_PADDING 添加到 openssl_encryptopenssl_decrypt

    示例:

    $e = openssl_encrypt($text, 'des-ede3-cbc', $key, OPENSSL_ZERO_PADDING, $iv);
    

    重要
    请记住,必须在加密和解密模式下都设置填充选项。

    【讨论】:

    • 感谢谷仓!我怀疑这与填充有关。你帮我解决了这个问题!
    • 很高兴能为您提供帮助,感谢您让我知道它解决了您的问题。我意识到这是一项遗留服务,但如果可能的话,我强烈建议您切换到 AES。但我确信我不是第一个提出这个建议的人。快乐编码
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    相关资源
    最近更新 更多