title: RSA encryption from Flex client and Corresponding Decryption from Web service
body: <p>I'm having a problem setting up RSA encryption/decryption mechanism between flex client and web service written in c#. The idea is this: I'll encrypt some text from flex and then decrypt it from web service.  I'm using as3crypto library from google. It is encrypting/decrypting text properly. I also have the code on the web service side to encrypt/decrypt properly. My problem is synchronizing them - basically sharing the public key to flex and keeping the private key to the web service. </p>
  
  <p>My flex "encrypt" function takes modulus and exponent of RSA to do text encryption, so how do i get these modulus and exponent attributes from the web service's RSACryptoServiceProvider, so they speak the same standard. 
  I tried the 
  RSAKeyInfo.Modulus
  RSAKeyInfo.Exponent
  from the web service and fed them to the flex client.
  After doing encryption on flex I took the cipher text and fed it to decrypt method on web service, but it is giving me "bad data" error message.</p>
  
  <pre><code>System.Security.Cryptography.CryptographicException: Bad Data.
  
     at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
     at System.Security.Cryptography.Utils._DecryptKey(SafeKeyHandle hPubKey, Byte[] key, Int32 dwFlags)
     at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
     at Microsoft.Samples.Security.PublicKey.App.RSADecrypt(Byte[] DataToDecrypt, RSAParameters RSAKeyInfo, Boolean DoOAEPPadding) in C:\Users
  \Me\Desktop\After Release\5-24-2011-webServiceCrypto\publickeycryptography\CS\PublicKeyCryptography\PublicKey.cs:line 219
  Encryption failed.
  </code></pre>
  
  <p>How do i make sure they are both using the same byte 64 or 128 byte encryption . ie the input from flex should fit to what is expected by the web service RSACryptoServiceProvider's decrypt method.
  (I'm assuming the size might be a problem, may be it's not - i'm lost)</p>
  
  <p>Here is the code, first flex client followed by web service c# code</p>
  
  <pre><code>private function encrypt():void {
                  var rsa:RSAKey = RSAKey.parsePublicKey(getModulus(), getExponent());
                  trace("Modulus Lenght: " + getModulus().length);
                  trace("Exponent Lenght : " + getExponent().length);
                  var data:ByteArray = getInput();  //returns byteArray of plainText
                  var dst:ByteArray = new ByteArray;
                  rsa.encrypt(data, dst, data.length);
                  trace("Enc Data: " + dst.toString() );
                  currentResult = Hex.fromArray(dst);
                  encryptedText = currentResult;
                  trace("Encrypted:: " + currentResult);
              }
  
              //For testing purposes
              private function decrypt():void {
                  var rsa:RSAKey = RSAKey.parsePrivateKey(getModulus(), getExponent(), getPrivate(), getP(), getQ(), getDMP1(), getDMQ1(), getCoeff());
                  var data:ByteArray = Hex.toArray(encryptedText);
                  trace("Byte array: " + data.toString());
                  var dst:ByteArray = new ByteArray;
                  rsa.decrypt(data, dst, data.length);
                  decryptedText = Hex.fromArray(dst);
                  trace("Decrypted text: " + Hex.toString(decryptedText));
              }
  </code></pre>
  
  <p>And web service part is as follows:</p>
  
  <pre><code>       try
          {
              //Create a UnicodeEncoder to convert between byte array and string.
              UnicodeEncoding ByteConverter = new UnicodeEncoding();
  
              //Create byte arrays to hold original, encrypted, and decrypted data.
              byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
              byte[] encryptedData;
              byte[] decryptedData;
  
              //Create a new instance of RSACryptoServiceProvider to generate
              //public and private key data.
              using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
              {
                  //Pass the data to ENCRYPT, the public key information 
                  //(using RSACryptoServiceProvider.ExportParameters(false),
                  //and a boolean flag specifying no OAEP padding.
                  encryptedData = RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false), false);
                  //Pass the data to DECRYPT, the private key information 
                  //(using RSACryptoServiceProvider.ExportParameters(true),
                  //and a boolean flag specifying no OAEP padding.
                  decryptedData = RSADecrypt(encryptedData, RSA.ExportParameters(true), false);
                  //Display the decrypted plaintext to the console. 
                  Console.WriteLine("\n\nDecrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
              }
          }
  
  static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
      {
          try
          {
              byte[] encryptedData;
              //Create a new instance of RSACryptoServiceProvider.
              using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
              {
  
                  //Import the RSA Key information. This only needs
                  //toinclude the public key information.
                  RSA.ImportParameters(RSAKeyInfo);
  
                  //Encrypt the passed byte array and specify OAEP padding.  
                  //OAEP padding is only available on Microsoft Windows XP or
                  //later.  
                  encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
              }
              return encryptedData;
          }
          //Catch and display a CryptographicException  
          //to the console.
          catch (CryptographicException e)
          {
              Console.WriteLine(e.Message);
  
              return null;
          }
  
      }
  
  
   static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
      {
          try
          {
              Console.WriteLine("Modulus Lenghth :" + RSAKeyInfo.Modulus.Length);
              Console.WriteLine("Exponent Length :" + RSAKeyInfo.Exponent.Length);
              byte[] decryptedData;
              //Create a new instance of RSACryptoServiceProvider.
              using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
              {
                  //Import the RSA Key information. This needs
                  //to include the private key information.
                  RSA.ImportParameters(RSAKeyInfo);
  
                  //Decrypt the passed byte array and specify OAEP padding.  
                  //OAEP padding is only available on Microsoft Windows XP or
                  //later.  
                  decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
              }
              return decryptedData;
          }
          //Catch and display a CryptographicException  
          //to the console.
          catch (CryptographicException e)
          {
              Console.WriteLine(e.ToString());
  
              return null;
          }
  
      }
  </code></pre>
  
  <p>I'm not quite sure if this RSA set up is the way to go... 
  Any kinda comment / advice/ or recommended solution is welcome,
  thanks guys</p>