C # encrypt PHP decrypt с использованием RSA

Я пытаюсь создать простой процесс дешифрования шифрования RSA между C # и PHP. Я выполнил шифрование на PHP и decrpyt на C # с помощью phpseclib (http://phpseclib.sourceforge.net/ ). Однако я получаю «Ошибка дешифрования в C: \ xampp \ htdocs \ Crypt \ RSA.php в строке 2103», которая является этой частью:

if ($lHash != $lHash2) {
        user_error('Decryption error', E_USER_NOTICE);
        return false;
    }

шифрование на C # я использовал эту кучу кода:

RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider(dwKeySize);
        rsaCryptoServiceProvider.FromXmlString(publickey);
        int keySize = dwKeySize / 8;
        byte[] bytes = Encoding.UTF32.GetBytes(inputString);
        // The hash function in use by the .NET RSACryptoServiceProvider here is SHA1
        // int maxLength = ( keySize ) - 2 - ( 2 * SHA1.Create().ComputeHash( rawBytes ).Length );
        int maxLength = keySize - 42;
        int dataLength = bytes.Length;
        int iterations = dataLength / maxLength;
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i <= iterations; i++)
        {
            byte[] tempBytes = new byte[(dataLength - maxLength * i > maxLength) ? maxLength : dataLength - maxLength * i];
            Buffer.BlockCopy(bytes, maxLength * i, tempBytes, 0, tempBytes.Length);
            byte[] encryptedBytes = rsaCryptoServiceProvider.Encrypt(tempBytes, true);
            // Be aware the RSACryptoServiceProvider reverses the order of encrypted bytes after encryption and before decryption.
            // If you do not require compatibility with Microsoft Cryptographic API (CAPI) and/or other vendors.
            // Comment out the next line and the corresponding one in the DecryptString function.
            Array.Reverse(encryptedBytes);
            // Why convert to base 64?
            // Because it is the largest power-of-two base printable using only ASCII characters
            stringBuilder.Append(Convert.ToBase64String(encryptedBytes));
        }
        string ciphertext = stringBuilder.ToString();

и мой базовый PHP-код для дешифрования:

$rsa->loadKeyfromXML($privatekey);  
$ciphertext = file_get_contents('cipher.txt');
$ciphertext = base64_decode(strrev($ciphertext));

//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

$plaintext = $rsa->decrypt($ciphertext);

Я пробовал PKC1, он также дал еще одну ошибку в Crypt / RSA.php


person relativelyPrime    schedule 03.04.2013    source источник
comment
Прошло некоторое время, но насколько я помню, я использовал phpseclib stackoverflow.com/a/4534385/2241072   -  person relativelyPrime    schedule 28.10.2019


Ответы (4)


ура, я сам нашел решение. Я изменил строчку в шифровании:

byte[] bytes = Encoding.UTF32.GetBytes(inputString);  ==> byte[] bytes = Encoding.Default.GetBytes(inputString);

а также, как сказал @Ryan:

$ciphertext = base64_decode(strrev($ciphertext));  ==> $ciphertext = strrev(base64_decode($ciphertext));

Спасибо за ваши попытки.

person relativelyPrime    schedule 04.04.2013

Поскольку вы делаете Array.Reverse на C #, я рискну предположить, что strrev в PHP не нужен.

Кроме того, Crypt_RSA phpseclib не имеет loadKeyfromXML. Откуда вы это берете? Выполнения $rsa->loadKey() должно быть достаточно.

Наконец, я предполагаю, что требуется PKCS1. Какую ошибку вы получаете при его использовании?

person neubert    schedule 03.04.2013
comment
да, $ rsa- ›loadKey () тоже работает, без разницы. для PKCS, как я прокомментировал, он, к сожалению, дает ту же ошибку - person relativelyPrime; 04.04.2013
comment
Вы пробовали без strrev? - person neubert; 04.04.2013
comment
yeap Я также пробовал с / out strrev и base64_decode. все еще выдает ошибку в той же строке в RSA.php. Также, когда я использую PKCS1, я получаю ошибку в строке: if (ord ($ em [0])! = 0 || ord ($ em [1]) ›2) { user_error ('Ошибка дешифрования', E_USER_NOTICE); вернуть ложь; } - person relativelyPrime; 04.04.2013

Мне кажется, что в PHP вы берете зашифрованный текст в кодировке Base64, меняете его местами, а затем пытаетесь его декодировать с помощью Base64? Я бы подумал, что вы хотите сначала его декодировать, а затем перевернуть результат. Это не одно и то же.

Я не могу сказать, нужна ли вообще такая реверсия.

person Ryan M    schedule 03.04.2013
comment
да, я только что взял код из источника, поэтому использую реверсирование. Для base64 шифрование с php и дешифрование на C # работали хорошо, и я использовал ту же операцию - person relativelyPrime; 04.04.2013
comment
Сначала попробовал декодировать, затем strrev с (out) PKCS1, все еще выдает ошибку в той же строке без PKCS1, а с PKCS1 он дает ошибку в: 'if (ord ($ em [0])! = 0 || ord ($ em [1]) ›2)». - person relativelyPrime; 04.04.2013

Я должен сказать, что не совсем понял вашу проблему, но, похоже, о том, как объединить шифрование RSA в C # и PHP. У меня также были некоторые проблемы с этим, и для всех, кто все еще интересовался, я написал рабочий проект, посвященный этому, программа C # и PHP-скрипт создают ключи RSA и обмениваются ими, а затем обмениваются данными в зашифрованном виде (см. здесь).

person Oliver    schedule 27.04.2015