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

C#和PHP加密兼容性-3DES ECB与PKCS7,c#,php,encryption,pkcs#7,3des,C#,Php,Encryption,Pkcs#7,3des,我有一个共同的问题,但网络上的各种解决方案似乎都不适合我 我有一个C#代码,用PKCS7加密3DES-ECB。我必须在PHP中也这样做,但得到的结果不同 这是我的C#代码: 我用php做了很多尝试。。。这只是其中之一: function apiEncode($data) { $key = "6702BC24DD0527E7"; //Pad for PKCS7 $blockSize = mcrypt_get_block_size('tripledes', 'ecb');

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

我有一个C#代码,用PKCS7加密3DES-ECB。我必须在PHP中也这样做,但得到的结果不同

这是我的C#代码:

我用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);
}
我使用的是随机键,您可以在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中实现。。看代码“tabbed”,就是我在c#side中进行哈希运算的地方。。如何在php one中实现它

解决方案

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#:

和PHP:

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

还是“小写OK”。。。通常,您应该使用AES和各种块链接模式中的一种,如CBC(需要IV),并且应该使用算法“加强”密码,如PBKDF2(需要PHP>=5.5)

好的,解决了这个问题。看,我都写了。

因为您使用的是一个短键,所以可能需要在php中复制该键的一部分。Mcrypt和C#可能以不同的方式期待这两个关键的3D。不如用24字节的键试试看。@Pieroalbert若要了解如何解决3DES与.NET的TripleDescryptoServiceProvider不兼容的问题,在这种特定情况下(您使用的是128位键),请尝试添加一个
$key.=substr($key,0,8)
将密钥从128位放大到192位。@PieroAlberto我的电脑上C#的输出是
hbJpiCNmXz8=
,因此与您编写的PHP相同。@PieroAlberto也许您需要一台新电脑:-)这就是我需要的!!谢谢@皮耶罗最好不要使用3DES或ECB模式。@ArtjomB。有不同层次的OK:-)是的,你是对的。AES+CBC是OK@ArtjomB. 尽管如此,据我所知3des是安全的。。。唯一的问题是PieroAlberto 3DES既旧又慢,最后它使用了112位的等效密钥长度。AES较新(但不是太新,在密码学中很重要),速度更快,是当前的“标准”。欧洲央行的问题是它没有IV,因此如果对同一文本加密两次,就会得到相同的加密输出,并且每个数据块都独立于其他数据块进行加密,因此如果在相同的“会话”数据中加密重复的数据,这些重复是显而易见的
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(); 
$key = "6702BC24DD0527E7";
$key = hash("sha256",$key,TRUE);
$key = substr($key,0,24);