TripleDES加密在C#和PHP没有出来相同(PKCS7,ECB)? [英] TripleDES Encrypting in C# and PHP not coming out the same (PKCS7, ECB)?

查看:177
本文介绍了TripleDES加密在C#和PHP没有出来相同(PKCS7,ECB)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几个小时试图找出这一点,但我只是不能让它工作。我有一个C#加密例程,我需要在PHP匹配。我不能更改C#版本,这不是一个选项(第三方是坚定的)。

I've spent a couple hours now trying to figure this out, but I just can't get it to work. I've got a C# encryption routine that I need to match in php. I can't change the C# version, that's not an option (3rd party is firm on this).

这里是C#代码:

//In C#
// Console.WriteLine(ApiEncode("testing", "56dsfkj3kj23asdf83kseegflkj43458afdl"));
// Results in: 
//     XvHbR/CsLTo=
public static string ApiEncode(string data, string secret)
{
  byte[] clear;

  var encoding = new UTF8Encoding();
  var md5 = new MD5CryptoServiceProvider();

  byte[] key = md5.ComputeHash(encoding.GetBytes(secret));

  TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
  des.Key = key;
  des.Mode = CipherMode.ECB;
  des.Padding = PaddingMode.PKCS7;

  byte[] input = encoding.GetBytes(data);
  try { clear = des.CreateEncryptor().TransformFinalBlock(input, 0, input.Length); }
  finally
  {
    des.Clear();
    md5.Clear();
  }

  return Convert.ToBase64String(clear);
}



这里是我在PHP中提出的最好的: p>

Here's the best of what I've come up with in PHP:

//In PHP
// echo apiEncode("testing", "56dsfkj3kj23asdf83kseegflkj43458afdl");
// Results in: 
//    5aqvY6q1T54=
function apiEncode($data, $secret)
{    
  //Generate a key from a hash
  $key = md5(utf8_encode($secret), true);
  //Create init vector  
  $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ecb), MCRYPT_RAND); 

  //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'); //, $iv);
  return base64_encode($encData);
}

据我所知,我正在处理PKCS7 PHP端。我不知道还有什么可以尝试。

To the best of my knowledge, I'm handling the PKCS7 padding properly on the PHP side. I'm not sure what else to try.

需要注意的是,C#正在Windows上运行,而PHP上的linux,不知道应该有区别。

One thing to note, the C# is happening on windows, and the PHP on linux, not sure that should make a difference.

推荐答案

PHP版本中的填充长度基于密码长度。这是不正确的。

The padding length in your PHP version is based on the length of the password. This is incorrect. It should be based on the length of your message instead.

尝试将 strlen($ password)替换为 strlen($ data)

第二个问题是 mcrypt 库需要24字节的密钥。三重DES应用常规DES三次,因此可以调用在每一轮DES K 1,K 2和K <3>中使用的8字节密钥, / sub>。有不同的方法来选择这些键。最安全的是选择三个不同的键。另一种方式是将K sub 3等于K sub 1。最不安全的方法(等效于DES)是使K <1> = K <2> = K <3> 。

The second problem is that the mcrypt library requires 24-byte keys. Triple DES applies regular DES three times, so you can call the 8-byte key used in each round of DES K1, K2, and K3. There are different ways to choose these keys. The most secure is to choose three distinct keys. Another way is to set K3 equal to K1. The least secure method (equivalent to DES) is to make K1 = K2 = K3.

大多数库都是聪明的,足以将16字节的3DES密钥解释为上面的第二个选项:K 3 = K 1 。 .NET实现是为你做的,但 mcrypt 库不是;相反,它设置K 3 = 0。您需要自己修复,并传递 mcrypt 一个24字节的密钥。

Most libraries are "smart" enough to interpret a 16-byte 3DES key as the second option above: K3 = K1. The .NET implementation is doing this for you, but the mcrypt library is not; instead, it's setting K3 = 0. You'll need to fix this yourself, and pass mcrypt a 24-byte key.

计算MD5哈希后,取 $ key 的前8个字节,并将它们附加到 $ key ,因此您有一个24字节的值传递给 mcrypt_encrypt()

After computing the MD5 hash, take the first 8 bytes of $key, and append them to the end of $key, so that you have a 24-byte value to pass to mcrypt_encrypt().

这篇关于TripleDES加密在C#和PHP没有出来相同(PKCS7,ECB)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆