1

I am trying to crypt AES Key and IV with RSA in C# and decrypt them with PHP using phpseclib. I tried to fix this problem for about 4 hours but I always get 'Decryption error on line 2495'. Seems to be something wrong with PKCS.

Temporary Private Key

<?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-----");?>

Temporary Public Key

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

Ciphertext after RSA encryption in C#(decrypted = "testkey" cause I removed the aes encryption for testing)

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

PHP (no change if strrev or not):

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# Encryption:

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);
    }

Function get called in 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) is line 2495

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
wHaT
  • 57
  • 2
  • 8
  • 1
    try to comment $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); – jhdxr Jan 19 '15 at 06:09
  • I tried that before. No changes in error message. – wHaT Jan 19 '15 at 11:57
  • I don't suppose you'd be able to post a copy of a full private key that reproduces the problem and the ciphertext you're unable to decrypt with that key? This would make it easier to reproduce the problem and from there diagnose. – neubert Jan 19 '15 at 20:56
  • No problem. I just created a new pair just for testing. You can get all you asked for at the beginning of my question. – wHaT Jan 19 '15 at 22:24
  • I don't think your private key is valid. I removed the `-----BEGIN RSA PRIVATE KEY-----` and do `-----END RSA PRIVATE KEY-----` from `RSA_Private` and did `base64_decode(substr(RSA_Private, 0, 1186))` and that works but `base64_decode(RSA_Private)` does not - it returns `bool(false)`. – neubert Jan 20 '15 at 17:09
  • I created a new pair with phpseclib and set them as new private and public key. Then I tried `base64_decode(RSA_Private)` and it worked for me. The error message is still there. I added the new keys and ciphertext to the question. – wHaT Jan 20 '15 at 17:55
  • Got it. Changed to xml key files. I also edited the code to the working one. – wHaT Jan 21 '15 at 18:32
  • @wHaT Please add what you just edited into the question as an answer. You can answer your own question, but it has to be separate, otherwise future users that visit your question wouldn't know what the problem is and where the solution is. Therefore I rolled back your edit. After you have provided the answer, you can also accept it or wait and see if there comes a better answer. – Artjom B. Jan 21 '15 at 18:35
  • Just did it as you said. I would like to see a solution for my question! – wHaT Jan 21 '15 at 18:45
  • Possible duplicate of [Encrypt and Decrypt text with RSA in PHP](http://stackoverflow.com/questions/4484246/encrypt-and-decrypt-text-with-rsa-in-php) – Scott Arciszewski Mar 06 '16 at 18:49

1 Answers1

1

Solution:

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));
}
wHaT
  • 57
  • 2
  • 8