使用Rijndael(C#)加密的PHP解密数据

我的任务是使用Php解密用C#加密的数据。我尝试使用phpseclib库。因此,这是C#中用于加密的现有代码:

    public static String EncryptMyText(string clearText,string Password)
    {
        if (clearText.Length == 0) return "";
        byte[] clearBytes = System.Text.Encoding.UTF8.GetBytes(clearText);
        // second parameter is "Ivan Medvedev" in string
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,new byte[] { 0x49,0x76,0x61,0x6e,0x20,0x4d,0x65,0x64,0x76 });
        byte[] encryptedData = Encrypt(clearBytes,pdb.GetBytes(32),pdb.GetBytes(16));
        return Convert.ToBase64String(encryptedData);
    }

    public static byte[] Encrypt(byte[] clearData,byte[] Key,byte[] IV)
    {
        try
        {
            MemoryStream ms = new MemoryStream();
            Rijndael alg = Rijndael.Create();
            alg.Key = Key;
            alg.IV = IV;
            CryptoStream cs = new CryptoStream(ms,alg.CreateEncryptor(),CryptoStreamMode.Write);
            cs.Write(clearData,clearData.Length);
            cs.Close();
            byte[] encryptedData = ms.ToArray();
            return encryptedData;
        }
        catch (Exception ex)
        {
            string message = ex.Message;
        }
        return null;
    }

    EncryptMyText("sometext","xxxxxxxxxxxxxxx"); // password have 15 characters length

无法更改此代码。所以这是我尝试使用phpseclib的内容:

$key = "xxxxxxxxxxxxxxx";
$salt = "Ivan Medvedev";
$cipher = new Rijndael();
$cipher->setPassword($cle,'pbkdf1','sha1',$salt);
$cipher->decrypt(base64_decode("someCryptedText"));

这时,代码以setPassword()调用引发的异常“派生密钥太长”而中断。

我尝试了许多操作,例如更改blockLengthKeyLenghth而不使用setPassword()

$cipher->setKeyLength(256);
$cipher->setBlockLength(128);

没有明显变化。

我几乎没有解密和密码方面的经验,因此我就所使用的C#代码挖掘了一些信息。在https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rijndael?view=netframework-4.8处查看Rijndael类。我尝试了几件事,对应该看的东西没有太多的想法。我什至不知道是否可以使用Phpseclib来解密此C#代码生成的数据。

感谢所有可以给我一些指导的人。

sunsunfuqi 回答:使用Rijndael(C#)加密的PHP解密数据

https://github.com/phpseclib/phpseclib/issues/1447#issuecomment-580594929可能会回答您的问题。引用:

根据https://crypto.stackexchange.com/q/22271/4520 PasswordDeriveBytes实现了PBKDF1的自定义版本。

尝试一下:

function pbkdf1ms(&$cipher,$password,$hash,$salt,$rounds)
{
    $keyLength = $cipher->getKeyLength() >> 3;
    $blockLength = $cipher->getBlockLength() >> 3;

    $dkLen = $keyLength + $blockLength;

    $hashObj = new Hash();
    $hashObj->setHash($hash);
    if ($dkLen > 100 * $hashObj->getLength()) {
        user_error('Derived key too long');
        return false;
    }

    $t = $password . $salt;
    for ($i = 0; $i < $rounds; ++$i) {
        $old = $t;
        $t = $hashObj->hash($t);
    }

    $ctr = 1;
    while ($dkLen > strlen($t)) {
        $t.= $hashObj->hash($ctr++ . $old);
    }

    $key = substr($t,$dkLen);

    $cipher->setKey(substr($key,$keyLength));
    //$cipher->setKey(substr($key,$keyLength));
    $remainingBytes = $hashObj->getLength() - $keyLength % $hashObj->getLength();
    $cipher->setIV(
        substr($key,$remainingBytes,$blockLength - $remainingBytes) .
        substr($key,$keyLength + $remainingBytes)
    );
}

$c = new Rijndael;
$c->setKeyLength(256);
pbkdf1ms($c,'xxxxxxxxxxxxxxx','sha1','Ivan Medvedev',100);

$c->decrypt(base64_decode("s@omeCryptedText"));
本文链接:https://www.f2er.com/2692661.html

大家都在问