C # RSA Encrypt - ›PHP RSA Decrypt

Я пытаюсь зашифровать AES Key и IV с помощью RSA на C # и расшифровать их с помощью PHP с помощью phpseclib. Я пытался решить эту проблему около 4 часов, но всегда получаю сообщение «Ошибка дешифрования в строке 2495». Кажется, что-то не так с PKCS.

Временный закрытый ключ

<?php define("RSA_Private", "-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQC/JPkdbqnnCTsfEbFlx/3bj+RP9wTdAh+f0Ndi55R4qBcrAIUv 1jTedYRkciAHIGSZgB2McymAuYzUtYW+22arD/ET/DiwwTP/+YPEJYenU2Zbfirb 2bO6yXzfTf9cpctWxx4k6MeVDXIQsZv5sUiFvSl8auNNzp22QVIH19tDlwIDAQAB AoGAV62wD84pZW8YjYHiK9v3GHYCtqOKuY41z2tOwXGU61u/dNxCO9U4Xyrs1d57 zokPXFImO7y/tupmLVQuy4N8rgO0BqB2t3YETpOlwmOF4CYl0Lkoa5mlQ1XvBXoU qbNU33UlJUNheLT0UM7lhwwnBTqNlfC1/bNXL8TYCsyt+KECQQDstdKRaip8YH20 DgB2301/91pCTAkw/vXEPi8GBVq4EN/hWSwpz+hDrJrbmSBnTkQ2IlWvYy3nghGB g/QwTaZ/AkEAzriR/Snqfif2fpSovp0ln8/A0AR0utq1FfvYWMkT9woqPR5iJjS7 ZcVX1U9ayC4fPypMz/BXafy9MGstllhG6QJAakZ387GmwZDQ3zYqHzTCpuF3NKzO s6DE1wbUNe/RezKYUaSnn14o+blVDaMCWV9aYLOppMTypy5Ojcegqs8yIQJADXjL 0tLbfFNAZilsAdgd7pdMeoH/1XmRWZhrFgYsrenUrN0BCnpfSBefTMB6KxeOY8Bu 9xIzsC2PasthUi34mQJAV5IvcjaOiMSed28LegOHTBXP5Qpu96GQGneD3x92AtM+ aRhEjMeoadetA0JQcPRJgVXTov5wir5xeCEUjpplGg== -----END RSA PRIVATE KEY-----");?>

Временный открытый ключ

<?php define("RSA_Public", "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/JPkdbqnnCTsfEbFlx/3bj+RP 9wTdAh+f0Ndi55R4qBcrAIUv1jTedYRkciAHIGSZgB2McymAuYzUtYW+22arD/ET /DiwwTP/+YPEJYenU2Zbfirb2bO6yXzfTf9cpctWxx4k6MeVDXIQsZv5sUiFvSl8 auNNzp22QVIH19tDlwIDAQAB -----END PUBLIC KEY-----");?>

Зашифрованный текст после шифрования RSA в C # (decrypted = "testkey", потому что я удалил шифрование aes для тестирования)

Cd/RsiVqKnEP2T9oTgnvRuHVKY09VfynLHIlinIGtW4PFrB2kKffIrIqRQKhob6bPIR4efjxhCn43AQ2gE5P/AMG/EDWk9HMJF8XuhdtsWfPmnqxVV4crpA2FZwh4BWdXq4N70ieWbuk+pRJ1dHGhLgFfphp4sVVopn3bPKw2VKI0O+MT4nUCHFac25owoFnMULzuxj60I9Qa/TIlCKwMNcv2r7ili/LvplPZIEnH2p/bR62TAUvty0yo9NTHZm+wlqyIUmA1/GrM0VHjmcnRjFQHp1zQreRspvRsbk=

PHP (без изменений, если strrev или нет):

public function RSADecryption($key, $iv) {
    $PrivateKeyFile = RSA_Private;
    $rsa = new Crypt_RSA();
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
    $rsa->loadKey($PrivateKeyFile);
    // decrypt key and iv for aes decryption
    $aes_key = base64_encode($rsa->decrypt(strrev((base64_decode($key)))));
    $aes_iv = base64_encode($rsa->decrypt(base64_decode($iv)));
    echo $aes_key;
    echo "<br />";
    echo $aes_iv;
}

Шифрование C #:

public static string RSAEncryption(string aes_key, string aes_iv, string publickey)
    {
        if (publickey.Contains("-----"))
        {
            // Get public key without -----....
            publickey = publickey.Split(new string[] { "-----" }, StringSplitOptions.RemoveEmptyEntries)[1];
        }

        // Remove "new line" characters
        publickey.Replace("\n", "");
        byte[] KeyToEncrypt = Encoding.Default.GetBytes(aes_key);
        byte[] IVToEncrypt = Encoding.Default.GetBytes(aes_iv);
        byte[] PublicKey = Encoding.Default.GetBytes(publickey);

        //Values to store encrypted symmetric keys.
        byte[] EncryptedKey;
        byte[] EncryptedIV;

        //Create a new instance of RSACryptoServiceProvider.
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

        //Get an instance of RSAParameters from ExportParameters function.
        RSAParameters RSAKeyInfo = RSA.ExportParameters(false);

        //Set RSAKeyInfo to the public key values.
        RSAKeyInfo.Modulus = PublicKey;
        //Import key parameters into RSA.
        RSA.ImportParameters(RSAKeyInfo);

        //Encrypt the symmetric key and IV.
        EncryptedKey = RSA.Encrypt(KeyToEncrypt, false);
        EncryptedIV = RSA.Encrypt(IVToEncrypt, false);
        System.IO.File.WriteAllText(@"C:\WriteTextCryptKey.txt", Convert.ToBase64String(EncryptedKey));
        System.IO.File.WriteAllText(@"C:\WriteTextCryptIV.txt", Convert.ToBase64String(EncryptedIV));
        return Convert.ToBase64String(EncryptedKey);
    }

Функция вызывается в phpseclib:

function _rsaes_pkcs1_v1_5_decrypt($c)
{
    // Length checking

    if (strlen($c) != $this->k) { // or if k < 11
        user_error('Decryption error');
        return false;
    }

    // RSA decryption

    $c = $this->_os2ip($c);
    $m = $this->_rsadp($c);

    if ($m === false) {
        user_error('Decryption error');
        return false;
    }
    $em = $this->_i2osp($m, $this->k);

    // EME-PKCS1-v1_5 decoding

    if (ord($em[0]) != 0 || ord($em[1]) > 2) {
        user_error('Decryption error');
        return false;
    }

    $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
    $m = substr($em, strlen($ps) + 3);

    if (strlen($ps) < 8) {
        user_error('Decryption error');
        return false;
    }

    // Output M

    return $m;
}

if (ord($em[0]) != 0 || ord($em[1]) > 2) - это строка 2495


person wHaT    schedule 18.01.2015    source источник
comment
попробуйте прокомментировать $ rsa- ›setEncryptionMode (CRYPT_RSA_ENCRYPTION_PKCS1);   -  person jhdxr    schedule 19.01.2015
comment
Я пробовал это раньше. В сообщении об ошибке нет изменений.   -  person wHaT    schedule 19.01.2015
comment
Я не думаю, что вы сможете опубликовать копию полного закрытого ключа, воспроизводящего проблему, и зашифрованный текст, который вы не можете расшифровать с помощью этого ключа? Это упростило бы воспроизведение проблемы и оттуда диагностику.   -  person neubert    schedule 19.01.2015
comment
Без проблем. Я только что создал новую пару для тестирования. Вы можете получить все, о чем просили, в начале моего вопроса.   -  person wHaT    schedule 20.01.2015
comment
Я не думаю, что ваш закрытый ключ действителен. Я удалил -----BEGIN RSA PRIVATE KEY----- и сделал -----END RSA PRIVATE KEY----- из RSA_Private и сделал base64_decode(substr(RSA_Private, 0, 1186)), и это работает, но base64_decode(RSA_Private) нет - он возвращает bool(false).   -  person neubert    schedule 20.01.2015
comment
Я создал новую пару с помощью phpseclib и установил их как новый закрытый и открытый ключи. Затем я попробовал base64_decode(RSA_Private), и у меня это сработало. Сообщение об ошибке все еще существует. Я добавил к вопросу новые ключи и зашифрованный текст.   -  person wHaT    schedule 20.01.2015
comment
Понятно. Поменял на ключевые файлы xml. Так же отредактировал код на рабочий.   -  person wHaT    schedule 21.01.2015
comment
@wHaT Пожалуйста, добавьте в вопрос то, что вы только что отредактировали, в качестве ответа. Вы можете ответить на свой вопрос, но он должен быть отдельным, иначе будущие пользователи, которые посетят ваш вопрос, не будут знать, в чем проблема и где находится решение. Поэтому я откатил вашу правку. После того, как вы предоставили ответ, вы также можете принять его или подождать и посмотреть, появится ли лучший ответ.   -  person Artjom B.    schedule 21.01.2015
comment
Просто сделал, как ты сказал. Хотелось бы увидеть решение своего вопроса!   -  person wHaT    schedule 21.01.2015
comment
Возможный дубликат Шифрование и дешифрование текста с помощью RSA в PHP   -  person Scott Arciszewski    schedule 06.03.2016


Ответы (1)


Решение:

C#:

public static string RSAEncryption(string aes_key, string aes_iv)
    {
        //encode key and iv to byte array
        byte[] KeyToEncrypt = Encoding.Default.GetBytes(aes_key);
        byte[] IVToEncrypt = Encoding.Default.GetBytes(aes_iv);

        //get RSA public key from xml file
        TextReader reader = new StreamReader("publicKey.xml");
        string publicKey = reader.ReadToEnd();
        reader.Close();
        MessageBox.Show(publicKey);

        //Values to store encrypted symmetric keys.
        byte[] EncryptedKey;
        byte[] EncryptedIV;

        //Create a new instance of RSACryptoServiceProvider.
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

        //set xml string as public key
        RSA.FromXmlString(publicKey);

        //Encrypt the symmetric key and IV.
        EncryptedKey = RSA.Encrypt(KeyToEncrypt, false);
        EncryptedIV = RSA.Encrypt(IVToEncrypt, false);
        System.IO.File.WriteAllText(@"C:\WriteTextCryptKey.txt", Convert.ToBase64String(EncryptedKey));
        System.IO.File.WriteAllText(@"C:\WriteTextCryptIV.txt", Convert.ToBase64String(EncryptedIV));
        return Convert.ToBase64String(EncryptedKey);
    }

PHP:

public function RSADecryption($key, $iv) {
    $PrivateKeyFile = RSA_Private;
    $rsa = new Crypt_RSA();
    $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
    $rsa->loadKey($PrivateKeyFile); //private key in xml
    // decrypt key and iv for aes decryption
    $aes_key = $rsa->decrypt(base64_decode($key));
    $aes_iv = $rsa->decrypt(base64_decode($iv));
}
person wHaT    schedule 21.01.2015