none
How Can i use the key file Generated by RSACryptoServiceProvider to encrypt with php? RRS feed

  • Question

  • I need to be able to encrypt data in PHP using a public key generate by .NET(RSACryptoServiceProvider).  I will then decrypt the data later in C# using the private key.

     

    Code Snippet

    <RSAKeyValue><Modulus>xU5JyaPNDKXI/h/uo5Vk89wZSz3zsB1+c+1IMYIQa+mCmuRCRPuoBI7ODSV2ndP6grfhdrWEzhpZtkI3SThbBh/3t+tfZ2PF8Iyv9ECN07V64nPCiJGhAnfENE+J9UD9Kw5czXHgZcBbpM5N0VfXmLSleaS65DDoNPtoStVy7ss=</Modulus><Exponent>AQAB</Exponent><P>4ScAjVrPZii/6lICAP2yDQiNEmNL74+5AcxNVDI0IombfDPIygrqEWmuDu0pngApQak7XnEnLbaDChILFiHPZQ==</P><Q>4FaYlse+cjrlPD/jk+GsTJeuP7yuQx8ztjVnQWVh6GKQP+uk1dAl6kcZOfLNR6LWwE3CSygt8PthTEw96Zbabw==</Q><DP>XvXtNLE9UjATqYeHEtXtV7Pok/3PVC3A8PIzFzTJaluxeXP51sU9rbRt1hvO9rXIsMnooU+GH7Cfmgq8JEyERQ==</DP><DQ>HXkC/vwq9xLpvuqd2XXSjxV2XQVK16Knxo5pjFvnawJX9S3eMADymj7Q/534firUj9snZXxX3MsJ015I3AFnnQ==</DQ><InverseQ>AM0fVCE3n2FKf2zb3CcDEge1Ko35VvMEL+LXgR87QwO2HScZSuLevGLi2SSAkB1vu8RSNzB028SZReeOZWnq4Q==</InverseQ><D>fI+GKdRNOTTYhQZnw8Im74T+OvArjf2wvUMJlqfD8jyDBYIhDCfL1MTK9KW4Er+moSuxHR5Pb0ZXaKa4/HKlk0aJ1jB2C+jg7zTSuPRNuS16BpVHaJYsQurCwZwElXMum+GxeXK/h3wXWq5HwebjqZr0aLUMZKRcweDPRoVFiRE=</D></RSAKeyValue>

     

    As you see this code snippet is a xml format private key. at .net platform,which can use encrypt or dencrypt.

    i have try the Extension Crypt RSA ( http://pear.php.net/reference/Crypt_RSA-1.0.0/elementindex_Crypt_RSA.html ) to help me encrypt data by php.but it haven't return a currect result. the data encrypted by php cann't dencrypt by c#.

     

    does the RSA algorithm provider by Crypt_RSA can give a stand result as c#?

    BTW :i just use the xmlkeystring like this.

    Code Snippet

    <?php
    require_once("Crypt/RSA.php");
    require_once("includes/Utils.class.php");
        $public_key_string = simplexml_load_string("<RSAKeyValue><Modulus>xU5JyaPNDKXI/h/uo5Vk89wZSz3zsB1+c+1IMYIQa+mCmuRCRPuoBI7ODSV2ndP6grfhdrWEzhpZtkI3SThbBh/3t+tfZ2PF8Iyv9ECN07V64nPCiJGhAnfENE+J9UD9Kw5czXHgZcBbpM5N0VfXmLSleaS65DDoNPtoStVy7ss=</Modulus><Exponent>AQAB</Exponent><P>4ScAjVrPZii/6lICAP2yDQiNEmNL74+5AcxNVDI0IombfDPIygrqEWmuDu0pngApQak7XnEnLbaDChILFiHPZQ==</P><Q>4FaYlse+cjrlPD/jk+GsTJeuP7yuQx8ztjVnQWVh6GKQP+uk1dAl6kcZOfLNR6LWwE3CSygt8PthTEw96Zbabw==</Q><DP>XvXtNLE9UjATqYeHEtXtV7Pok/3PVC3A8PIzFzTJaluxeXP51sU9rbRt1hvO9rXIsMnooU+GH7Cfmgq8JEyERQ==</DP><DQ>HXkC/vwq9xLpvuqd2XXSjxV2XQVK16Knxo5pjFvnawJX9S3eMADymj7Q/534firUj9snZXxX3MsJ015I3AFnnQ==</DQ><InverseQ>AM0fVCE3n2FKf2zb3CcDEge1Ko35VvMEL+LXgR87QwO2HScZSuLevGLi2SSAkB1vu8RSNzB028SZReeOZWnq4Q==</InverseQ><D>fI+GKdRNOTTYhQZnw8Im74T+OvArjf2wvUMJlqfD8jyDBYIhDCfL1MTK9KW4Er+moSuxHR5Pb0ZXaKa4/HKlk0aJ1jB2C+jg7zTSuPRNuS16BpVHaJYsQurCwZwElXMum+GxeXK/h3wXWq5HwebjqZr0aLUMZKRcweDPRoVFiRE=</D></RSAKeyValue>");
        $key =new Crypt_RSA_Key(base64_decode($public_key_string->Modulus),base64_decode($public_key_string->Exponent),"public");
        echo "<pre>";
        print_r($key);
        echo "</pre>";
        $rsa_obj = new Crypt_RSA();
        //try encrypt data
        echo "encrypted result is:<br/>".$rsa_obj->encrypt("this is a smple text.",$key)
        ?>

     

     

    but the encrypted data cann't decrypt by c#?where is the problem?what should i do with php codes?
    Monday, May 19, 2008 2:17 PM

Answers

  • Tim Lai,

     

    How is your problem going? Based on your post, you would like to decrypt data in C# that encrypted in PHP class library with the same algorithm. The .NET Framework provides you the RSACryptoServiceProvider to encrypt/decrypt the data easily. For the PHP part, I know little about it. However, I would like to provide you the thread by Matthew M. below:

     

    C# Crypto Asymmetric w/ RSA? Need to encrypt in PHP using Openssl. Confused on certificates!

     

    Solution:
    I had to use X509 certificates.
    This Blog Post Helped with Makecert
    That blog explained how to make the certs, etc. I created them, then exported it twice - one into a BASE-64 encoded public key format, and one into PKCS#12 PFX format for the private key.

    I sent the public key to the PHP server, and it worked using openssl routines for the encryption. I then copied the returned BASE64 string (I converted it) to my C# app. I plugged it in.. and came up with something similar to the following:

    Code Snippet

                X509Certificate2 myCert2 = new X509Certificate2(@"C:\mycerts\myprivatekeyfile.pfx");

                RSACryptoServiceProvider rsa1 = (RSACryptoServiceProvider)myCert2.PrivateKey;

                byte[] plain = rsa1.Decrypt(Convert.FromBase64String(decryptDataInBase64), false);

                MessageBox.Show(System.Text.Encoding.UTF8.GetString(plain));

     

    I read it in using X509Certificate2, created a new RSACryptoServiceProvider, and read out the private key

    from the X509Cert object.. turns out its castable.

     

    I hope the OP's solution can provide you some idea.

    Thursday, May 22, 2008 6:54 AM
  • thank you for your reply, i also found this article by google.but this does not meet scene,  thank you all the same.

    i have already solved the problem now,i'd like to post the Solution .infact it's so easy to use rsakey file generated by .net .

     

    -------------rsa.class.php-------------------

    Code Snippet

    <?php
    /*
     * Some constants
     */
    define("BCCOMP_LARGER", 1);
    class RSA
    {
     /*
      * PHP implementation of the RSA algorithm
      * (C) Copyright 2004 Edsko de Vries, Ireland
      *
      * Licensed under the GNU Public License (GPL)
      *
      * This implementation has been verified against [3]
      * (tested Java/PHP interoperability).
      *
      * References:
      * [1] "Applied Cryptography", Bruce Schneier, John Wiley & Sons, 1996
      * [2] "Prime Number Hide-and-Seek", Brian Raiter, Muppetlabs (online)
      * [3] "The Bouncy Castle Crypto Package", Legion of the Bouncy Castle,
      *      (open source cryptography library for Java, online)
      * [4] "PKCS #1: RSA Encryption Standard", RSA Laboratories Technical Note,
      *      version 1.5, revised November 1, 1993
      */

     /*
      * Functions that are meant to be used by the user of this PHP module.
      *
      * Notes:
      * - $key and $modulus should be numbers in (decimal) string format
      * - $message is expected to be binary data
      * - $keylength should be a multiple of 8, and should be in bits
      * - For rsa_encrypt/rsa_sign, the length of $message should not exceed
      *   ($keylength / 8) - 11 (as mandated by [4]).
      * - rsa_encrypt and rsa_sign will automatically add padding to the message.
      *   For rsa_encrypt, this padding will consist of random values; for rsa_sign,
      *   padding will consist of the appropriate number of 0xFF values (see [4])
      * - rsa_decrypt and rsa_verify will automatically remove message padding.
      * - Blocks for decoding (rsa_decrypt, rsa_verify) should be exactly
      *   ($keylength / 8) bytes long.
      * - rsa_encrypt and rsa_verify expect a public key; rsa_decrypt and rsa_sign
      *   expect a private key.
      */

     /**
      * rsa encrypt data
      *
      * @param binary string $message
      * @param unknown_type $public_key
      * @param numbers $modulus
      * @param numbers $keylength
      * @return binary data
      */
     function rsa_encrypt($message, $public_key, $modulus, $keylength)
     {
      $padded = RSA::add_PKCS1_padding($message, true, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $encrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($encrypted, $keylength / 8);

      return $result;
     }

     function rsa_decrypt($message, $private_key, $modulus, $keylength)
     {
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);

      return RSA::remove_PKCS1_padding($result, $keylength / 8);
     }

     function rsa_sign($message, $private_key, $modulus, $keylength)
     {
      $padded = RSA::add_PKCS1_padding($message, false, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $signed = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($signed, $keylength / 8);

      return $result;
     }

     function rsa_verify($message, $public_key, $modulus, $keylength)
     {
      return RSA::rsa_decrypt($message, $public_key, $modulus, $keylength);
     }

     function rsa_kyp_verify($message, $public_key, $modulus, $keylength)
     {
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);

      return RSA::remove_KYP_padding($result, $keylength / 8);
     }


     /*
      * The actual implementation.
      * Requires BCMath support in PHP (compile with --enable-bcmath)
      */

     //--
     // Calculate (p ^ q) mod r
     //
     // We need some trickery to [2]:
     //   (a) Avoid calculating (p ^ q) before (p ^ q) mod r, because for typical RSA
     //       applications, (p ^ q) is going to be _WAY_ too large.
     //       (I mean, __WAY__ too large - won't fit in your computer's memory.)
     //   (b) Still be reasonably efficient.
     //
     // We assume p, q and r are all positive, and that r is non-zero.
     //
     // Note that the more simple algorithm of multiplying $p by itself $q times, and
     // applying "mod $r" at every step is also valid, but is O($q), whereas this
     // algorithm is O(log $q). Big difference.
     //
     // As far as I can see, the algorithm I use is optimal; there is no redundancy
     // in the calculation of the partial results.
     //--
     function pow_mod($p, $q, $r)
     {
      // Extract powers of 2 from $q
      $factors = array();
      $div = $q;
      $power_of_two = 0;
      while(bccomp($div, "0") == BCCOMP_LARGER)
      {
       $rem = bcmod($div, 2);
       $div = bcdiv($div, 2);

       if($rem) array_push($factors, $power_of_two);
       $power_of_two++;
      }

      // Calculate partial results for each factor, using each partial result as a
      // starting point for the next. This depends of the factors of two being
      // generated in increasing order.
      $partial_results = array();
      $part_res = $p;
      $idx = 0;
      foreach($factors as $factor)
      {
       while($idx < $factor)
       {
        $part_res = bcpow($part_res, "2");
        $part_res = bcmod($part_res, $r);

        $idx++;
       }

       array_push($partial_results, $part_res);
      }

      // Calculate final result
      $result = "1";
      foreach($partial_results as $part_res)
      {
       $result = bcmul($result, $part_res);
       $result = bcmod($result, $r);
      }

      return $result;
     }

     //--
     // Function to add padding to a decrypted string
     // We need to know if this is a private or a public key operation [4]
     //--
     function add_PKCS1_padding($data, $isPublicKey, $blocksize)
     {
      $pad_length = $blocksize - 3 - strlen($data);

      if($isPublicKey)
      {
       $block_type = "\x02";

       $padding = "";
       for($i = 0; $i < $pad_length; $i++)
       {
        $rnd = mt_rand(1, 255);
        $padding .= chr($rnd);
       }
      }
      else
      {
       $block_type = "\x01";
       $padding = str_repeat("\xFF", $pad_length);
      }

      return "\x00" . $block_type . $padding . "\x00" . $data;
     }

     //--
     // Remove padding from a decrypted string
     // See [4] for more details.
     //--
     function remove_PKCS1_padding($data, $blocksize)
     {
      assert(strlen($data) == $blocksize);
      $data = substr($data, 1);

      // We cannot deal with block type 0
      if($data{0} == '\0')
      die("Block type 0 not implemented.");

      // Then the block type must be 1 or 2
      assert(($data{0} == "\x01") || ($data{0} == "\x02"));
      // Remove the padding
      $offset = strpos($data, "\0", 1);
      return substr($data, $offset + 1);
     }

     //--
     // Remove "kyp" padding
     // (Non standard)
     //--
     function remove_KYP_padding($data, $blocksize)
     {
      assert(strlen($data) == $blocksize);

      $offset = strpos($data, "\0");
      return substr($data, 0, $offset);
     }

     //--
     // Convert binary data to a decimal number
     //--
     function binary_to_number($data)
     {
      $base = "256";
      $radix = "1";
      $result = "0";

      for($i = strlen($data) - 1; $i >= 0; $i--)
      {
       $digit = ord($data{$i});
       $part_res = bcmul($digit, $radix);
       $result = bcadd($result, $part_res);
       $radix = bcmul($radix, $base);
      }

      return $result;
     }

     //--
     // Convert a number back into binary form
     //--
     function number_to_binary($number, $blocksize)
     {
      $base = "256";
      $result = "";

      $div = $number;
      while($div > 0)
      {
       $mod = bcmod($div, $base);
       $div = bcdiv($div, $base);

       $result = chr($mod) . $result;
      }

      return str_pad($result, $blocksize, "\x00", STR_PAD_LEFT);
     }
    }
    ?>


     

     

    -------------RSAProcessor.class.php------------------------

    Code Snippet

    <?php
    require_once("rsa.class.php");

    class RSAProcessor
    {
     
     private $public_key = null;
     
     private $private_key = null;
     
     private $modulus = null;
     
     private $key_length = "1024";
     
     
     public function __construct($xmlRsakey=null,$type=null)
     {
             $xmlObj = null;
     
       if($xmlRsakey==null)
              {
               $xmlObj = simplexml_load_file("xmlfile/RSAKey.xml");
              }
              elseif($type==RSAKeyType::XMLFile)
              {
               $xmlObj = simplexml_load_file($xmlRsakey);
              }
              else
              {
               $xmlObj = simplexml_load_string($xmlRsakey);
              }
             $this->modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
       $this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
       $this->key_length = strlen(base64_decode($xmlObj->Modulus))*8;
     }
     /**
      * get public key
      *
      * @return string public key
      */
     public function getPublicKey()
     {
      //return base64_encode(RSA::number_to_binary($this->public_key,($this->key_length)/8));
      return $this->public_key;
     }
     public function getPrivateKey()
     {
      //return base64_encode(RSA::number_to_binary($this->private_key,($this->key_length)/8));
      return $this->private_key;
     }
     public function getKeyLength()
     {
      return $this->key_length;
     }
     public function getModulus()
     {
      return $this->modulus;
     }
     /**
      * encrypt data
      *
      * @param string $data
      * @return base64 encoded  binary string
      */
     public function encrypt($data)
     {
      return base64_encode(RSA::rsa_encrypt($data,$this->public_key,$this->modulus,$this->key_length));
     }
     
     public function dencrypt($data)
     {
      return RSA::rsa_decrypt($data,$this->private_key,$this->modulus,$this->key_length);
     }
     
     public function sign($data)
     {
      return RSA::rsa_sign($data,$this->private_key,$this->modulus,$this->key_length);
     }
     
     public function verify($data)
     {
      return RSA::rsa_verify($data,$this->public_key,$this->modulus,$this->key_length);
     }
    }

    class RSAKeyType
    {
     const XMLFile = 0;
     const XMLString = 1;
    }
    ?>

     

     

    -------------- encrypt data with public key-----------------

    Code Snippet

    <?php
    require_once("RSAProcessor.class.php");
    $processor = new RSAProcessor

    ("<RSAKeyValue><Modulus>m6ljoeWhmnd0oRnsVEH5iNw3B8+vKVu7v7CVfMyf6bnKEzHa62TRmT/baJiSevoI/vgm2ph/s1JrQQTaGiErHicigwSC

    Aw7+i05WFbnz7tOyiiJJVMfsdd+v7Xan9Hiud05FzxoMbM8vpiMHPEIDbGJ1MiXyupTVkz2WcMHyBoJ4S189opktZ43pviUhy0PeuWkyoU7zR54akPmK

    Yg+z5Zr1r7K8lUZ1a3TThfJGxTQR/uZMtZz/q8QF0AANVQ/eyahTv9icBzBoDuncS0Y5l3vqogW1C/ltJvhJpvSn/OgjbRjuixCAptOUmRd13sDWU95/

    x0bMq+Lg68lj2OjJ1Q==</Modulus><Exponent>AQAB</Exponent><P>zfvdBsMLlmo+4PAUYLgSV2xyyVa7ZqFjkJaAE4EbYuH24EoZjrzeiJR++D

    FUT/GUhjfZ5eZ/5e29dXwk0sKUw6nHzBdBtOPp5fr4t5SKLEcWY+J+zLUSOlhG9NUkohFf6+Miy2Y7BLpXVrcl6UwXV0ak8KkTPB2l/aIMwYj5dgc=</

    P><Q>wXV0sA3nDzoSDQA/4QSu/WIlBhkA3jZ7K7G9Z9rpP1A0vH+bZeyCIyo52u8ahGuYbubaizF1XMp+Xv3Mh2KmRbt7+UptwEwbFAUiiad2a312mqm

    j7IJd7gRjGkyzKEm+6fpNeY3NFLNVNhccBqzhNkRoM22xnvQcImD10XVAakM=</Q><DP>wd1HdCLEWCfc0DYE59a2pINUMXyo2foRTDbpifHcRZ+ojAY

    Rsc6+nsssCQnccXVMNVqBgSgEvfGYe+eAfMBX5SN5APPuioJrVGF2DsoFlZC+WPoGH0JYSoNlHO8yEDrMDaXzzH2GFHgQ1XOAged0nFbHzB1FFjJNVL5

    cxRXWu6c=</DP><DQ>QDKuCk5SwubOXqoaiJ15RHRxPNjHRPZnYVSWOgSXKn9/QJ5H/0bA2NKGaHS4JAFgkEzjcRV0kNpRnUwztymxa6qPtWZRjWK0Ca

    y6jVuZHIqB9UkeMLoCWZ3zFSMmwNPYGuUJGLFJwPjR6iU5E64C/nMs8QQR0WHIhFAQwvVZ7uk=</DQ><InverseQ>JckMSlJR10VZdnp83VPjrZ/Z+63

    CGu3tWHm7f4DJ8IwjJWr8FlCpbSwiP6a4e9Upv6bUn/tOj2gY6MMq5G5yTKm2SCRvpUKRu4NCmWAt7vlFv0Z6pkXlTOpzvVjv3v16+dIZOA5Zn+v7+r1

    xbdYdH20KRAbiBO3MfQP7s+VJJvM=</InverseQ><D>W1xrBr2hQOj1wgxWAgoK7IHbprEFrK+TnWmGA46SGPsbmHJ9fAVbY6fwHg7Wgmk4WHXLUCeLY

    /Nu0eWIISfwh60Oe3ls2WC2k4qxyeSvQDBuLNb81U7WAUT9m9E1uK4QMCP3oxs1ybM80zTh7UMNgVK0WG+fbFUomVffcWTTqW+Fu12PEIO+UR/85oq+x

    qVlTzYAEzt1OE9IhkYiRzi99ePXeH2gFltzJ/fb/7jLsDTkhM2eiYTGyOTZmBnen6c6a8b9LFTY4Bc0bGpk5ezHkub6F8p2ZgL/JgIOJMyRZICjDjs+9

    k9PTmMTFsCF6xzHY15Fg25xIDYzIyx1rrRUjQ==</D></RSAKeyValue>",RSAKeyType::XMLString);
    $rs =  $processor->encrypt("Hello,It's Works.");
    echo $rs;
    ?>

     

     

    with the front codes.you can easy to encrypt data by public key generate by .net programe.

     

    Saturday, May 24, 2008 9:52 AM

All replies

  • <RSAKeyValue><Modulus>xU5JyaPNDKXI/h/uo5Vk89wZSz3zsB1+c+1IMYIQa+mCmuRCRPuoBI7ODSV2ndP6grfhdrWEzhpZtkI3SThbBh/3t+tfZ2PF8Iyv9ECN07V64nPCiJGhAnfENE+J9UD9Kw5czXHgZcBbpM5N0VfXmLSleaS65DDoNPtoStVy7ss=</Modulus><Exponent>AQAB</Exponent><P>4ScAjVrPZii/6lICAP2yDQiNEmNL74+5AcxNVDI0IombfDPIygrqEWmuDu0pngApQak7XnEnLbaDChILFiHPZQ==</P><Q>4FaYlse+cjrlPD/jk+GsTJeuP7yuQx8ztjVnQWVh6GKQP+uk1dAl6kcZOfLNR6LWwE3CSygt8PthTEw96Zbabw==</Q><DP>XvXtNLE9UjATqYeHEtXtV7Pok/3PVC3A8PIzFzTJaluxeXP51sU9rbRt1hvO9rXIsMnooU+GH7Cfmgq8JEyERQ==</DP><DQ>HXkC/vwq9xLpvuqd2XXSjxV2XQVK16Knxo5pjFvnawJX9S3eMADymj7Q/534firUj9snZXxX3MsJ015I3AFnnQ==</DQ><InverseQ>AM0fVCE3n2FKf2zb3CcDEge1Ko35VvMEL+LXgR87QwO2HScZSuLevGLi2SSAkB1vu8RSNzB028SZReeOZWnq4Q==</InverseQ><D>fI+GKdRNOTTYhQZnw8Im74T+OvArjf2wvUMJlqfD8jyDBYIhDCfL1MTK9KW4Er+moSuxHR5Pb0ZXaKa4/HKlk0aJ1jB2C+jg7zTSuPRNuS16BpVHaJYsQurCwZwElXMum+GxeXK/h3wXWq5HwebjqZr0aLUMZKRcweDPRoVFiRE=</D></RSAKeyValue>

    ==============
    XML FORMAT RSA KEY
    Tuesday, May 20, 2008 2:53 AM
  • Tim Lai,

     

    How is your problem going? Based on your post, you would like to decrypt data in C# that encrypted in PHP class library with the same algorithm. The .NET Framework provides you the RSACryptoServiceProvider to encrypt/decrypt the data easily. For the PHP part, I know little about it. However, I would like to provide you the thread by Matthew M. below:

     

    C# Crypto Asymmetric w/ RSA? Need to encrypt in PHP using Openssl. Confused on certificates!

     

    Solution:
    I had to use X509 certificates.
    This Blog Post Helped with Makecert
    That blog explained how to make the certs, etc. I created them, then exported it twice - one into a BASE-64 encoded public key format, and one into PKCS#12 PFX format for the private key.

    I sent the public key to the PHP server, and it worked using openssl routines for the encryption. I then copied the returned BASE64 string (I converted it) to my C# app. I plugged it in.. and came up with something similar to the following:

    Code Snippet

                X509Certificate2 myCert2 = new X509Certificate2(@"C:\mycerts\myprivatekeyfile.pfx");

                RSACryptoServiceProvider rsa1 = (RSACryptoServiceProvider)myCert2.PrivateKey;

                byte[] plain = rsa1.Decrypt(Convert.FromBase64String(decryptDataInBase64), false);

                MessageBox.Show(System.Text.Encoding.UTF8.GetString(plain));

     

    I read it in using X509Certificate2, created a new RSACryptoServiceProvider, and read out the private key

    from the X509Cert object.. turns out its castable.

     

    I hope the OP's solution can provide you some idea.

    Thursday, May 22, 2008 6:54 AM
  • thank you for your reply, i also found this article by google.but this does not meet scene,  thank you all the same.

    i have already solved the problem now,i'd like to post the Solution .infact it's so easy to use rsakey file generated by .net .

     

    -------------rsa.class.php-------------------

    Code Snippet

    <?php
    /*
     * Some constants
     */
    define("BCCOMP_LARGER", 1);
    class RSA
    {
     /*
      * PHP implementation of the RSA algorithm
      * (C) Copyright 2004 Edsko de Vries, Ireland
      *
      * Licensed under the GNU Public License (GPL)
      *
      * This implementation has been verified against [3]
      * (tested Java/PHP interoperability).
      *
      * References:
      * [1] "Applied Cryptography", Bruce Schneier, John Wiley & Sons, 1996
      * [2] "Prime Number Hide-and-Seek", Brian Raiter, Muppetlabs (online)
      * [3] "The Bouncy Castle Crypto Package", Legion of the Bouncy Castle,
      *      (open source cryptography library for Java, online)
      * [4] "PKCS #1: RSA Encryption Standard", RSA Laboratories Technical Note,
      *      version 1.5, revised November 1, 1993
      */

     /*
      * Functions that are meant to be used by the user of this PHP module.
      *
      * Notes:
      * - $key and $modulus should be numbers in (decimal) string format
      * - $message is expected to be binary data
      * - $keylength should be a multiple of 8, and should be in bits
      * - For rsa_encrypt/rsa_sign, the length of $message should not exceed
      *   ($keylength / 8) - 11 (as mandated by [4]).
      * - rsa_encrypt and rsa_sign will automatically add padding to the message.
      *   For rsa_encrypt, this padding will consist of random values; for rsa_sign,
      *   padding will consist of the appropriate number of 0xFF values (see [4])
      * - rsa_decrypt and rsa_verify will automatically remove message padding.
      * - Blocks for decoding (rsa_decrypt, rsa_verify) should be exactly
      *   ($keylength / 8) bytes long.
      * - rsa_encrypt and rsa_verify expect a public key; rsa_decrypt and rsa_sign
      *   expect a private key.
      */

     /**
      * rsa encrypt data
      *
      * @param binary string $message
      * @param unknown_type $public_key
      * @param numbers $modulus
      * @param numbers $keylength
      * @return binary data
      */
     function rsa_encrypt($message, $public_key, $modulus, $keylength)
     {
      $padded = RSA::add_PKCS1_padding($message, true, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $encrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($encrypted, $keylength / 8);

      return $result;
     }

     function rsa_decrypt($message, $private_key, $modulus, $keylength)
     {
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);

      return RSA::remove_PKCS1_padding($result, $keylength / 8);
     }

     function rsa_sign($message, $private_key, $modulus, $keylength)
     {
      $padded = RSA::add_PKCS1_padding($message, false, $keylength / 8);
      $number = RSA::binary_to_number($padded);
      $signed = RSA::pow_mod($number, $private_key, $modulus);
      $result = RSA::number_to_binary($signed, $keylength / 8);

      return $result;
     }

     function rsa_verify($message, $public_key, $modulus, $keylength)
     {
      return RSA::rsa_decrypt($message, $public_key, $modulus, $keylength);
     }

     function rsa_kyp_verify($message, $public_key, $modulus, $keylength)
     {
      $number = RSA::binary_to_number($message);
      $decrypted = RSA::pow_mod($number, $public_key, $modulus);
      $result = RSA::number_to_binary($decrypted, $keylength / 8);

      return RSA::remove_KYP_padding($result, $keylength / 8);
     }


     /*
      * The actual implementation.
      * Requires BCMath support in PHP (compile with --enable-bcmath)
      */

     //--
     // Calculate (p ^ q) mod r
     //
     // We need some trickery to [2]:
     //   (a) Avoid calculating (p ^ q) before (p ^ q) mod r, because for typical RSA
     //       applications, (p ^ q) is going to be _WAY_ too large.
     //       (I mean, __WAY__ too large - won't fit in your computer's memory.)
     //   (b) Still be reasonably efficient.
     //
     // We assume p, q and r are all positive, and that r is non-zero.
     //
     // Note that the more simple algorithm of multiplying $p by itself $q times, and
     // applying "mod $r" at every step is also valid, but is O($q), whereas this
     // algorithm is O(log $q). Big difference.
     //
     // As far as I can see, the algorithm I use is optimal; there is no redundancy
     // in the calculation of the partial results.
     //--
     function pow_mod($p, $q, $r)
     {
      // Extract powers of 2 from $q
      $factors = array();
      $div = $q;
      $power_of_two = 0;
      while(bccomp($div, "0") == BCCOMP_LARGER)
      {
       $rem = bcmod($div, 2);
       $div = bcdiv($div, 2);

       if($rem) array_push($factors, $power_of_two);
       $power_of_two++;
      }

      // Calculate partial results for each factor, using each partial result as a
      // starting point for the next. This depends of the factors of two being
      // generated in increasing order.
      $partial_results = array();
      $part_res = $p;
      $idx = 0;
      foreach($factors as $factor)
      {
       while($idx < $factor)
       {
        $part_res = bcpow($part_res, "2");
        $part_res = bcmod($part_res, $r);

        $idx++;
       }

       array_push($partial_results, $part_res);
      }

      // Calculate final result
      $result = "1";
      foreach($partial_results as $part_res)
      {
       $result = bcmul($result, $part_res);
       $result = bcmod($result, $r);
      }

      return $result;
     }

     //--
     // Function to add padding to a decrypted string
     // We need to know if this is a private or a public key operation [4]
     //--
     function add_PKCS1_padding($data, $isPublicKey, $blocksize)
     {
      $pad_length = $blocksize - 3 - strlen($data);

      if($isPublicKey)
      {
       $block_type = "\x02";

       $padding = "";
       for($i = 0; $i < $pad_length; $i++)
       {
        $rnd = mt_rand(1, 255);
        $padding .= chr($rnd);
       }
      }
      else
      {
       $block_type = "\x01";
       $padding = str_repeat("\xFF", $pad_length);
      }

      return "\x00" . $block_type . $padding . "\x00" . $data;
     }

     //--
     // Remove padding from a decrypted string
     // See [4] for more details.
     //--
     function remove_PKCS1_padding($data, $blocksize)
     {
      assert(strlen($data) == $blocksize);
      $data = substr($data, 1);

      // We cannot deal with block type 0
      if($data{0} == '\0')
      die("Block type 0 not implemented.");

      // Then the block type must be 1 or 2
      assert(($data{0} == "\x01") || ($data{0} == "\x02"));
      // Remove the padding
      $offset = strpos($data, "\0", 1);
      return substr($data, $offset + 1);
     }

     //--
     // Remove "kyp" padding
     // (Non standard)
     //--
     function remove_KYP_padding($data, $blocksize)
     {
      assert(strlen($data) == $blocksize);

      $offset = strpos($data, "\0");
      return substr($data, 0, $offset);
     }

     //--
     // Convert binary data to a decimal number
     //--
     function binary_to_number($data)
     {
      $base = "256";
      $radix = "1";
      $result = "0";

      for($i = strlen($data) - 1; $i >= 0; $i--)
      {
       $digit = ord($data{$i});
       $part_res = bcmul($digit, $radix);
       $result = bcadd($result, $part_res);
       $radix = bcmul($radix, $base);
      }

      return $result;
     }

     //--
     // Convert a number back into binary form
     //--
     function number_to_binary($number, $blocksize)
     {
      $base = "256";
      $result = "";

      $div = $number;
      while($div > 0)
      {
       $mod = bcmod($div, $base);
       $div = bcdiv($div, $base);

       $result = chr($mod) . $result;
      }

      return str_pad($result, $blocksize, "\x00", STR_PAD_LEFT);
     }
    }
    ?>


     

     

    -------------RSAProcessor.class.php------------------------

    Code Snippet

    <?php
    require_once("rsa.class.php");

    class RSAProcessor
    {
     
     private $public_key = null;
     
     private $private_key = null;
     
     private $modulus = null;
     
     private $key_length = "1024";
     
     
     public function __construct($xmlRsakey=null,$type=null)
     {
             $xmlObj = null;
     
       if($xmlRsakey==null)
              {
               $xmlObj = simplexml_load_file("xmlfile/RSAKey.xml");
              }
              elseif($type==RSAKeyType::XMLFile)
              {
               $xmlObj = simplexml_load_file($xmlRsakey);
              }
              else
              {
               $xmlObj = simplexml_load_string($xmlRsakey);
              }
             $this->modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
       $this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
       $this->key_length = strlen(base64_decode($xmlObj->Modulus))*8;
     }
     /**
      * get public key
      *
      * @return string public key
      */
     public function getPublicKey()
     {
      //return base64_encode(RSA::number_to_binary($this->public_key,($this->key_length)/8));
      return $this->public_key;
     }
     public function getPrivateKey()
     {
      //return base64_encode(RSA::number_to_binary($this->private_key,($this->key_length)/8));
      return $this->private_key;
     }
     public function getKeyLength()
     {
      return $this->key_length;
     }
     public function getModulus()
     {
      return $this->modulus;
     }
     /**
      * encrypt data
      *
      * @param string $data
      * @return base64 encoded  binary string
      */
     public function encrypt($data)
     {
      return base64_encode(RSA::rsa_encrypt($data,$this->public_key,$this->modulus,$this->key_length));
     }
     
     public function dencrypt($data)
     {
      return RSA::rsa_decrypt($data,$this->private_key,$this->modulus,$this->key_length);
     }
     
     public function sign($data)
     {
      return RSA::rsa_sign($data,$this->private_key,$this->modulus,$this->key_length);
     }
     
     public function verify($data)
     {
      return RSA::rsa_verify($data,$this->public_key,$this->modulus,$this->key_length);
     }
    }

    class RSAKeyType
    {
     const XMLFile = 0;
     const XMLString = 1;
    }
    ?>

     

     

    -------------- encrypt data with public key-----------------

    Code Snippet

    <?php
    require_once("RSAProcessor.class.php");
    $processor = new RSAProcessor

    ("<RSAKeyValue><Modulus>m6ljoeWhmnd0oRnsVEH5iNw3B8+vKVu7v7CVfMyf6bnKEzHa62TRmT/baJiSevoI/vgm2ph/s1JrQQTaGiErHicigwSC

    Aw7+i05WFbnz7tOyiiJJVMfsdd+v7Xan9Hiud05FzxoMbM8vpiMHPEIDbGJ1MiXyupTVkz2WcMHyBoJ4S189opktZ43pviUhy0PeuWkyoU7zR54akPmK

    Yg+z5Zr1r7K8lUZ1a3TThfJGxTQR/uZMtZz/q8QF0AANVQ/eyahTv9icBzBoDuncS0Y5l3vqogW1C/ltJvhJpvSn/OgjbRjuixCAptOUmRd13sDWU95/

    x0bMq+Lg68lj2OjJ1Q==</Modulus><Exponent>AQAB</Exponent><P>zfvdBsMLlmo+4PAUYLgSV2xyyVa7ZqFjkJaAE4EbYuH24EoZjrzeiJR++D

    FUT/GUhjfZ5eZ/5e29dXwk0sKUw6nHzBdBtOPp5fr4t5SKLEcWY+J+zLUSOlhG9NUkohFf6+Miy2Y7BLpXVrcl6UwXV0ak8KkTPB2l/aIMwYj5dgc=</

    P><Q>wXV0sA3nDzoSDQA/4QSu/WIlBhkA3jZ7K7G9Z9rpP1A0vH+bZeyCIyo52u8ahGuYbubaizF1XMp+Xv3Mh2KmRbt7+UptwEwbFAUiiad2a312mqm

    j7IJd7gRjGkyzKEm+6fpNeY3NFLNVNhccBqzhNkRoM22xnvQcImD10XVAakM=</Q><DP>wd1HdCLEWCfc0DYE59a2pINUMXyo2foRTDbpifHcRZ+ojAY

    Rsc6+nsssCQnccXVMNVqBgSgEvfGYe+eAfMBX5SN5APPuioJrVGF2DsoFlZC+WPoGH0JYSoNlHO8yEDrMDaXzzH2GFHgQ1XOAged0nFbHzB1FFjJNVL5

    cxRXWu6c=</DP><DQ>QDKuCk5SwubOXqoaiJ15RHRxPNjHRPZnYVSWOgSXKn9/QJ5H/0bA2NKGaHS4JAFgkEzjcRV0kNpRnUwztymxa6qPtWZRjWK0Ca

    y6jVuZHIqB9UkeMLoCWZ3zFSMmwNPYGuUJGLFJwPjR6iU5E64C/nMs8QQR0WHIhFAQwvVZ7uk=</DQ><InverseQ>JckMSlJR10VZdnp83VPjrZ/Z+63

    CGu3tWHm7f4DJ8IwjJWr8FlCpbSwiP6a4e9Upv6bUn/tOj2gY6MMq5G5yTKm2SCRvpUKRu4NCmWAt7vlFv0Z6pkXlTOpzvVjv3v16+dIZOA5Zn+v7+r1

    xbdYdH20KRAbiBO3MfQP7s+VJJvM=</InverseQ><D>W1xrBr2hQOj1wgxWAgoK7IHbprEFrK+TnWmGA46SGPsbmHJ9fAVbY6fwHg7Wgmk4WHXLUCeLY

    /Nu0eWIISfwh60Oe3ls2WC2k4qxyeSvQDBuLNb81U7WAUT9m9E1uK4QMCP3oxs1ybM80zTh7UMNgVK0WG+fbFUomVffcWTTqW+Fu12PEIO+UR/85oq+x

    qVlTzYAEzt1OE9IhkYiRzi99ePXeH2gFltzJ/fb/7jLsDTkhM2eiYTGyOTZmBnen6c6a8b9LFTY4Bc0bGpk5ezHkub6F8p2ZgL/JgIOJMyRZICjDjs+9

    k9PTmMTFsCF6xzHY15Fg25xIDYzIyx1rrRUjQ==</D></RSAKeyValue>",RSAKeyType::XMLString);
    $rs =  $processor->encrypt("Hello,It's Works.");
    echo $rs;
    ?>

     

     

    with the front codes.you can easy to encrypt data by public key generate by .net programe.

     

    Saturday, May 24, 2008 9:52 AM
  • I've googled your solution and it's wonderful, but my scenarion is a bit different. I need to sing data in PHP and verify it on .NET side. The thing I've stumbled upon is how would I "load" private_key out of XML (RSAKeyValue). Could you please help me with this?
    Tuesday, September 30, 2008 10:24 AM
  • Load your private key xml (obtained from rsa.ToXmlString(true)) instead of your private key. In theory you should be using your privat e key then to sign etc :)
    Monday, June 29, 2009 8:12 PM
  • How would I decrypt using the above solution in PHP? It never loads the PrivateKey.

    As well, the Encrypt() function takes more than 30 seconds, is there any way to speed it up?


    Brian
    Monday, April 26, 2010 11:23 PM
  • Just in case anyone else has turned up from Google, Bing or anywhere else! The libraries above don't work properly as 'Dark Slipstream' says.

    I have found a way to get full functionality (encrypt, decrypt, sign & verify) with a 'pure' PHP solution, you need phpseclib and then some minor alteration to import the .NET private / public keys.

    I've created a class that extends the main Crypt_RSA class within phpseclib that has the adjustments already made on my blog:

    http://www.codeblog.co.uk/2011/04/12/other-stuff/using-php-to-encrypt-decrypt-sign-verify-data-with-a-net-generated-xml-rsa-key/

    I've verified that the all of the methods outputs match that from a .NET 4 C# RSA Provider, it's also much quicker that other options.

    Oliver


    Tuesday, April 12, 2011 10:15 PM
  • Just in case anyone else has turned up from Google, Bing or anywhere else! The libraries above don't work properly as 'Dark Slipstream' says.

    I have found a way to get full functionality (encrypt, decrypt, sign & verify) with a 'pure' PHP solution, you need phpseclib and then some minor alteration to import the .NET private / public keys.

    I've created a class that extends the main Crypt_RSA class within phpseclib that has the adjustments already made on my blog:

    http://www.codeblog.co.uk/2011/04/12/other-stuff/using-php-to-encrypt-decrypt-sign-verify-data-with-a-net-generated-xml-rsa-key/

    I've verified that the all of the methods outputs match that from a .NET 4 C# RSA Provider, it's also much quicker than other options.

    Oliver


    Tuesday, April 12, 2011 10:17 PM
  • Good job Oliver, I also wondered about this topic and then used your solution to import XML formatted keys into PHP. I needed some extra effort though to be able to do the reverse, that is export a RSA key created by PHP and read this PEM format with C#, further one has to be a little bit careful about the encoding though. I wrote a complete working solution consisting of key creation in both the C# and PHP program, key exhange and exchanging of encrypted messages, in case anybody else is interested, you find it here: http://csharp-tricks-en.blogspot.de/2015/04/rsa-with-c-and-php.html.

    The other Oliver

    Edit: I just figured that phpseclib already supports XML key formats, so now it has gotten pretty simple (and I recommend this over my answer above): http://csharp-tricks-en.blogspot.de/2015/04/rsa-with-c-and-php_27.html


    Sunday, April 26, 2015 2:30 PM