C# 和 PHP 加密兼容性 - 3DES ECB 与 PKCS7

标签 c# php encryption pkcs#7 3des

我有一个常见问题,但网络上的各种解决方案似乎都不适合我。

我有 C# 代码,可以使用 PKCS7 加密 3DES-ECB。我必须在 PHP 中执行相同的操作,但得到不同的结果。

这是我的 C# 代码:

        public string Encrypt(string toEncrypt, string key)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
        System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //Always release the resources and flush data
            // of the Cryptographic service provide. Best Practice
            hashmd5.Clear();            
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

我在 php 中做了很多尝试...这只是其中之一:

function apiEncode($data)
{    
  $key = "6702BC24DD0527E7";

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
  return base64_encode($encData);
}

我使用的是随 secret 钥,您可以在 php 示例代码中找到它。

当输入为“00010”时,C# 代码返回“FcXBCikZU64=”,而 php 则返回“FIg+xqod9iY=” >”。

为什么?我想我正在做我在博客/教程/等中找到的所有内容...那么,我的情况有什么问题?

更新:

我已经添加了,但仍然是坏消息......

$key .= substr($key,0,8);

function apiEncode($data)
{    
  $key = "6702BC24DD0527E7";

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  $key .= substr($key,0,8); // append the first 8 bytes onto the end

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb'); //, $iv);
  return base64_encode($encData);
}

现在输出是hbJpiCNmXz8=...仍然不是我需要的..

UPDATE2:问题是,在 C# 端,我创建了一个哈希,但我不知道如何在 php 中执行此操作。查看代码“选项卡式”,这就是我所做的地方c# 端的哈希值..我怎样才能在 php 端做到这一点?

解决方案:

function apiEncode($data)
{    
  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  $key = "6702BC24DD0527E7";
  $key = md5($key,TRUE);
  $key .= substr($key,0,8);
  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
  return base64_encode($encData);
}

 $crypt = apiEncode("00010");     
    echo "CRYPT: $crypt";

最佳答案

PHP 代码:

$key = "6702BC24DD0527E7";
$key = md5($key,TRUE);
$key .= substr($key,0,8);

C# 代码“正常”。

“ok”在这里是一个大词。我可能会使用 SHA256 并将其修剪为 24 字节:

C#:

SHA256Managed sha256 = new SHA256Managed();
keyArray = sha256.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
Array.Resize(ref keyArray, 24);
//Always release the resources and flush data
// of the Cryptographic service provide. Best Practice
sha256.Clear(); 

和 PHP:

$key = "6702BC24DD0527E7";
$key = hash("sha256",$key,TRUE);
$key = substr($key,0,24);

并且仍然是“小写OK”...通常您应该使用AES和各种 block 链模式之一,例如CBC(需要IV),并且密码应该使用算法“加强”,像 PBKDF2(需要 PHP >= 5.5)

关于C# 和 PHP 加密兼容性 - 3DES ECB 与 PKCS7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31115861/

相关文章:

c# - 如何在 EndRequest 中使用 Autofac?

php - 如何使用PHP检查SQL中表中的最大数字

java - 在Android上解密 "SunJCE"AES加密数据

ruby-on-rails - 保护 iOS 应用程序和 Rails 应用程序之间通信的最简单方法是什么?

.net - 使用 AesManaged 解密之前验证 key /IV ?或者在 CryptographicException 发生之前避免它?

c# - 引用 C# 变量时如何处理 JavaScript 中的双引号

c# - DropDownList binding get Eval()、XPath() 和 Bind() 等数据绑定(bind)方法只能在数据绑定(bind)控件异常的上下文中使用

C# > VB 转换,RelayCommand 的行为不同

PHP 将二维数组按年和月分组为多维数组

php - 文件 "phinx.yml"不存在