Расшифруйте данные, используя PHP, которые были зашифрованы с помощью Rijndael (C#) - PullRequest
2 голосов
/ 29 января 2020

Моя задача - расшифровать данные, зашифрованные в C#, используя Php. Я пытаюсь использовать библиотеку 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, 0x65, 0x64, 0x65, 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, 0, 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().

I пробовал много вещей, таких как изменение blockLength и KeyLenghth и не использование setPassword()

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

без каких-либо заметных изменений.

У меня мало опыта в расшифровке и шифровании, поэтому я выкопал некоторую информацию об используемом коде C#. Глядя на класс Rijndael здесь https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rijndael?view=netframework-4.8. Я перепробовал несколько вещей, и у меня было немного идей о том, что мне следует искать. Я даже не знаю, возможно ли использовать Phpseclib для расшифровки данных, сделанных с помощью этого C# кода.

Спасибо всем, кто мог бы дать мне некоторое руководство.

1 Ответ

1 голос
/ 31 января 2020

Похоже, 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, 0, $dkLen);

    $cipher->setKey(substr($key, 0, $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"));
...