gpt4 book ai didi

c# - 将 C# TripleDESCryptoServiceProvider 加密移植到 PHP

转载 作者:搜寻专家 更新时间:2023-10-31 20:41:27 26 4
gpt4 key购买 nike

有一个用 C# 编写的项目,它使用以下代码对数据库中的数据进行加密/解密:

public string EncryptString(string Text)
{
byte[] IV = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
string Key = "abcdef";
byte[] buffer = Encoding.UTF8.GetBytes(Text);
TripleDESCryptoServiceProvider triple = new TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
triple.IV = IV;
triple.Key = md5.ComputeHash(ASCIIEncoding.UTF8.GetBytes(Key));
byte[] encodeText = triple.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length);
string user = Convert.ToBase64String(encodeText);
return user;
}

public static string DecryptString(string EncryptText)
{
byte[] IV = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
string Key = "abcdef";
byte[] decodeText = null;
byte[] buffer = Convert.FromBase64String(EncryptText);
TripleDESCryptoServiceProvider triple = new TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
triple.IV = IV;
triple.Key = md5.ComputeHash(ASCIIEncoding.UTF8.GetBytes(Key));
decodeText = triple.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length);
return Encoding.UTF8.GetString(decodeText);
}

现在我应该在 PHP 中做同样的事情。到目前为止,我已经接近以下代码:

define('CIPHER', 'tripledes');
define('MODE', 'cbc');

function Encrypt($data)
{
$iv = chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8);
$key = 'abcdef';
$tripleKey = substr(md5($key), 0, mcrypt_get_key_size(CIPHER, MODE));
$encodedText = mcrypt_encrypt(CIPHER, $tripleKey, $data, MODE, $iv);
return base64_encode($encodedText);
}

function Decrypt($data)
{
$iv = chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8);
$key = 'abcdef';
$tripleKey = substr(md5($key), 0, mcrypt_get_key_size(CIPHER, MODE));
$decodedText = mcrypt_decrypt(CIPHER, $tripleKey, base64_decode($data), MODE, $iv);
return $decodedText;
}

但我无法解密由 C# 代码加密的字符串!我不是加密专家,谁能告诉我应该使用哪种加密算法和模式?

最佳答案

您的主要问题在于 key 的处理。一个问题是微不足道的:在 PHP 中,md5函数默认返回哈希的十六进制转储,而您需要原始二进制值来匹配 C# 的 MD5CryptoServiceProvider.ComputeHash()。 .为此,只需将一个 true 参数添加到 PHP 调用 (md5(key, true))。

另一个问题有点复杂:MD5 返回一个 128 位的散列,而 3DES 使用一个 192 位的 key (实际上,168 位的 key ,其余的是奇偶校验位,但我们在这里忽略它) .当您向 PHP 实现提供太短的 key 时,它 pads the key using zero bytes ;然而,3DES 的 .NET/CSP 实现似乎从头开始重复 key 字节(环绕 key )。因此,为了匹配 PHP 中的 .NET 行为,您需要手动包装 key ($key . $key)。

最后一期是padding : PHP 使用零填充数据,而 .NET 默认使用 PKCS#7 填充。如果需要正确处理padding,需要在加密时加上,解密时去掉。

define('CIPHER', 'tripledes');
define('MODE', 'cbc');

function Encrypt($data)
{
$iv = chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8);
$key = 'abcdef';

// determine key bytes from the key text, using MD5 and wrapping around
$key = md5($key, true);
$key = $key . $key;
$tripleKey = substr($key, 0, mcrypt_get_key_size(CIPHER, MODE));

// add PKCS#7 padding
$blocksize = mcrypt_get_block_size(CIPHER, MODE);
$paddingSize = $blocksize - (strlen($data) % $blocksize);
$data .= str_repeat(chr($paddingSize), $paddingSize);

$encodedText = mcrypt_encrypt(CIPHER, $tripleKey, $data, MODE, $iv);
return base64_encode($encodedText);
}

function Decrypt($data)
{
$iv = chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8);

// determine key bytes from the key text, using MD5 and wrapping around
$key = 'abcdef';
$key = md5($key, true);
$key = $key . $key;
$tripleKey = substr($key, 0, mcrypt_get_key_size(CIPHER, MODE));

$decodedText = mcrypt_decrypt(CIPHER, $tripleKey, base64_decode($data), MODE, $iv);

// check and remove PKCS#7 padding
if (!$decodedText) return $decodedText;
$lastByte = ord($decodedText[strlen($decodedText) - 1]);
if ($lastByte == 0 || $lastByte > mcrypt_get_block_size(CIPHER, MODE)) return FALSE;
$paddingText = substr($decodedText, -$lastByte, $lastByte);
$decodedText = substr($decodedText, 0, -$lastByte);
if ($paddingText != str_repeat(chr($lastByte), $lastByte)) return FALSE;

return $decodedText;
}

但是,正如上面的评论员所说,由于多种原因,这并不是一个真正好的密码实现。 (而且我对这些调整的实现也没有真正加强。)

关于c# - 将 C# TripleDESCryptoServiceProvider 加密移植到 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20583327/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com