gpt4 book ai didi

c# - 如何将此 C# Rijndael 加密转换为 PHP?

转载 作者:可可西里 更新时间:2023-11-01 01:06:48 24 4
gpt4 key购买 nike

关于 SO 已经有一些有用的问题:

但是我的特殊情况仍然有困难。

我尝试了各种方法,但最终收到错误 “IV 参数必须与 block 大小一样长” 或与结果哈希不匹配的文本。

我对加密的了解还不足以弄清楚我做错了什么。

这是 php 版本:

$pass = 'hello';
$salt = 'application-salt';

echo Encrypt('hello', 'application-salt');

function Encrypt($pass, $salt)
{
$derived = PBKDF1($pass, $salt, 100, 16);
$key = bin2hex(substr($derived, 0, 8));
$iv = bin2hex(substr($derived, 8, 8));
return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $pass, MCRYPT_MODE_CBC, $iv);
}

function PBKDF1($pass, $salt, $count, $dklen)
{
$t = $pass.$salt;
$t = sha1($t, true);
for($i=2; $i <= $count; $i++)
{
$t = sha1($t, true);
}
$t = substr($t,0,$dklen-1);
return $t;
}

和 C# 版本:

Console.WriteLine(Encrypt("hello", "application-salt"));
// output: "Hk4he+qKGsO5BcL2HDtbkA=="

public static string Encrypt(string clearText, string Password)
{
byte[] clearData = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });

MemoryStream ms = new MemoryStream();
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(clearData, 0, clearData.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();

return Convert.ToBase64String(encryptedData);
}

我希望能够在一个新的基于 php 的应用程序中验证用户登录,该应用程序将与现有 C# 应用程序通信到同一个 MySQL 数据库。我打算加密密码并将生成的哈希值与存储在数据库中的哈希值进行比较以进行身份​​验证。

如有任何指点,我们将不胜感激。

编辑:

我意识到在 C# 函数中,PasswordDeriveBytes 被调用并传递一个字节数组作为参数,我在 PHP 版本中没有类似的参数。我发现这源自 Codeproject example并且 ASCII 中的字节数组拼写为“Ivan Medvedev”,我认为他是示例作者。很遗憾,我无法更改此设置。

最佳答案

下面的代码片段可能对正在寻找从 C# 到 PHP 的精确转换的人有帮助

<?php
class Foo {
protected $mcrypt_cipher = MCRYPT_RIJNDAEL_128;
protected $mcrypt_mode = MCRYPT_MODE_CBC;

public function decrypt($key, $iv, $encrypted)
{
return mcrypt_decrypt($this->mcrypt_cipher, $key, base64_decode($encrypted), $this->mcrypt_mode, $iv);
}

public function encrypt($key, $iv, $password)
{
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$padding = $block - (strlen($password) % $block);
$password .= str_repeat(chr($padding), $padding);
return mcrypt_encrypt($this->mcrypt_cipher, $key, $password, $this->mcrypt_mode, $iv);
}
}
$foo = new Foo;
$pass = 'p@ss';
$salt = 's@1t';

$key = PBKDF1($pass, $salt, 2, 32);

$iv = "@1B2c3D4e5F6g7H8";

$encrypted = $foo->encrypt($key,$iv,'test@123');

$encrypted = base64_encode($encrypted);

echo 'Encrypted: '.$encrypted.'</br>';
echo 'Decrypted: '.$foo->decrypt($key, $iv, $encrypted);



function PBKDF1($pass, $salt, $count, $cb)
{
static $base;
static $extra;
static $extracount= 0;
static $hashno;
static $state = 0;

if ($state == 0)
{
$hashno = 0;
$state = 1;

$key = $pass . $salt;
$base = sha1($key, true);
for($i = 2; $i < $count; $i++)
{
$base = sha1($base, true);
}
}

$result = "";

if ($extracount > 0)
{
$rlen = strlen($extra) - $extracount;
if ($rlen >= $cb)
{
$result = substr($extra, $extracount, $cb);
if ($rlen > $cb)
{
$extracount += $cb;
}
else
{
$extra = null;
$extracount = 0;
}
return $result;
}
$result = substr($extra, $rlen, $rlen);
}

$current = "";
$clen = 0;
$remain = $cb - strlen($result);
while ($remain > $clen)
{
if ($hashno == 0)
{
$current = sha1($base, true);
}
else if ($hashno < 1000)
{
$n = sprintf("%d", $hashno);
$tmp = $n . $base;
$current .= sha1($tmp, true);
}
$hashno++;
$clen = strlen($current);
}

// $current now holds at least as many bytes as we need
$result .= substr($current, 0, $remain);

// Save any left over bytes for any future requests
if ($clen > $remain)
{
$extra = $current;
$extracount = $remain;
}

return $result;
}

关于c# - 如何将此 C# Rijndael 加密转换为 PHP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9011635/

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